Commit 935fb288 by Richard Kenner

(tstdi): Optimized for "d" case.

(movqi): Allow moving "i" into "a".
(zero_extendsidi2): Alternatives merged.
(extendplussidi): Fixed when operands 0 and 1 share a register.
(adddi_sexthishl32): Constraints reordered for better reload.
(adddi3,subdi_sexthishl32,subdi3,negdi2): Likewise.
(ashldi_sexthi): Accept "m" as operand 0.
(ashldi_const32): Alternatives merged.
(ashift patterns): Output "lsl" instead of "asl".
(beq0_di): If condition codes already set, output only branch insn.
(bne0_di,bge0_di,blt0_di): Likewise.

From-SVN: r11783
parent 2dedbe1f
......@@ -100,8 +100,7 @@
;;- instructions and issue a library call rather than trapping into
;;- the kernel. The affected instructions are: divs.l <ea>,Dr:Dq;
;;- divu.l <ea>,Dr:Dq; muls.l <ea>,Dr:Dq; mulu.l <ea>,Dr:Dq; and
;;- fscale. The TARGET_68060 flag turns the use of the opcodes
;;- off.
;;- fscale. The TARGET_68060 flag turns the use of the opcodes off.
;;- FPA port explanation:
......@@ -292,23 +291,36 @@
;; (set (cc0) (const_int foo)) has no mode information. Such insns will
;; be folded while optimizing anyway.
(define_expand "tstdi"
[(parallel
(define_insn "tstdi"
[(set (cc0)
(match_operand:DI 0 "nonimmediate_operand" "d"))
(clobber (match_dup 1))])]
""
"operands[1] = gen_reg_rtx (DImode);")
(define_insn ""
[(set (cc0)
(match_operand:DI 1 "nonimmediate_operand" "0"))
(clobber (match_operand:DI 0 "register_operand" "=d"))]
(match_operand:DI 0 "nonimmediate_operand" "am,d"))
(clobber (match_scratch:SI 1 "=X,d"))
(clobber (match_scratch:DI 2 "=d,X"))]
""
"*
{
if (which_alternative == 0)
{
rtx xoperands[2];
xoperands[0] = operands[2];
xoperands[1] = operands[0];
output_move_double (xoperands);
cc_status.flags |= CC_REVERSED;
return \"neg%.l %R2\;negx%.l %2\";
}
if (find_reg_note (insn, REG_DEAD, operands[0]))
{
cc_status.flags |= CC_REVERSED;
return \"neg%.l %R0\;negx%.l %0\";
}
else
/*
** 'sub' clears %1, and also clears the X cc bit
** 'tst' sets the Z cc bit according to the low part of the DImode operand
** 'subx %1' (i.e. subx #0) acts as a (non-existent) tstx on the high part
*/
return \"sub%.l %1,%1\;tst%.l %R0\;subx%.l %1,%0\";
}")
(define_insn "tstsi"
......@@ -762,7 +774,7 @@
[(set (match_operand:SI 0 "general_operand" "=g")
(const_int 0))]
;; clr insns on 68000 read before writing.
;; This isn't so on the 68010, but we have no alternative for it.
;; This isn't so on the 68010, but we have no TARGET_68010.
"(TARGET_68020
|| !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))"
"*
......@@ -847,7 +859,7 @@
&& (DATA_REG_P (operands[0])
|| GET_CODE (operands[0]) == MEM)
/* clr insns on 68000 read before writing.
This isn't so on the 68010, but we have no alternative for it. */
This isn't so on the 68010, but we have no TARGET_68010. */
&& (TARGET_68020
|| !(GET_CODE (operands[0]) == MEM
&& MEM_VOLATILE_P (operands[0]))))
......@@ -915,7 +927,7 @@
&& (DATA_REG_P (operands[0])
|| GET_CODE (operands[0]) == MEM)
/* clr insns on 68000 read before writing.
This isn't so on the 68010, but we have no alternative for it. */
This isn't so on the 68010, but we have no TARGET_68010. */
&& (TARGET_68020
|| !(GET_CODE (operands[0]) == MEM
&& MEM_VOLATILE_P (operands[0]))))
......@@ -926,7 +938,7 @@
(define_insn "movqi"
[(set (match_operand:QI 0 "general_operand" "=d,*a,m,m,?*a")
(match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi,?*a,m"))]
(match_operand:QI 1 "general_operand" "dmi*a,di*a,dmi,?*a,m"))]
""
"*
{
......@@ -1050,9 +1062,10 @@
}
/* clr and st insns on 68000 read before writing.
This isn't so on the 68010, but we have no alternative for it. */
if (TARGET_68020
|| !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
This isn't so on the 68010, but we have no TARGET_68010. */
if (!ADDRESS_REG_P (operands[0])
&& (TARGET_68020
|| !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
{
if (operands[1] == const0_rtx)
return \"clr%.b %0\";
......@@ -1089,7 +1102,7 @@
{
if (operands[1] == const0_rtx
/* clr insns on 68000 read before writing.
This isn't so on the 68010, but we have no alternative for it. */
This isn't so on the 68010, but we have no TARGET_68010. */
&& (TARGET_68020
|| !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
return \"clr%.b %0\";
......@@ -1420,18 +1433,18 @@
;; this is the canonical form for (lshiftrt:DI x 32)
(define_insn "zero_extendsidi2"
[(set (match_operand:DI 0 "general_operand" "ro,<,>")
(zero_extend:DI (match_operand:SI 1 "general_operand" "rm,rm,rm")))]
[(set (match_operand:DI 0 "general_operand" "rm")
(zero_extend:DI (match_operand:SI 1 "general_operand" "rm")))]
""
"*
{
CC_STATUS_INIT;
if (which_alternative == 2)
return \"clr%.l %0\;move%.l %1,%0\";
if (which_alternative == 1)
return \"move%.l %1,%0\;clr%.l %0\";
if (GET_CODE (operands[0]) == REG)
operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
return \"move%.l %1,%0\;clr%.l %0\";
else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
return \"clr%.l %0\;move%.l %1,%0\";
else
operands[2] = adj_offsettable_operand (operands[0], 4);
if (ADDRESS_REG_P (operands[0]))
......@@ -1681,10 +1694,15 @@
operands[1] = operands[2];
operands[2] = tmp;
}
if (GET_CODE (operands[1]) == REG
&& REGNO (operands[1]) == REGNO (operands[3]))
output_asm_insn (\"add%.l %2,%3\", operands);
else
output_asm_insn (\"move%.l %2,%3\;add%.l %1,%3\", operands);
if (TARGET_68020)
return \"move%.l %2,%3\;add%.l %1,%3\;smi %0\;extb%.l %0\";
return \"smi %0\;extb%.l %0\";
else
return \"move%.l %2,%3\;add%.l %1,%3\;smi %0\;ext%.w %0\;ext%.l %0\";
return \"smi %0\;ext%.w %0\;ext%.l %0\";
}")
(define_insn "extendhisi2"
......@@ -2018,24 +2036,22 @@
}")
(define_insn "adddi_sexthishl32"
[(set (match_operand:DI 0 "general_operand" "=o,d,a")
[(set (match_operand:DI 0 "general_operand" "=o,a,*d,*d")
(plus:DI (ashift:DI (sign_extend:DI
(match_operand:HI 1 "general_operand" "rm,rm,rm"))
(match_operand:HI 1 "general_operand" "rm,rm,rm,rm"))
(const_int 32))
(match_operand:DI 2 "general_operand" "0,0,0")))
(clobber (match_scratch:SI 3 "=&d*a,a*d,X"))]
(match_operand:DI 2 "general_operand" "0,0,0,0")))
(clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
""
"*
{
CC_STATUS_INIT;
if (ADDRESS_REG_P (operands[0]))
return \"add%.w %1,%0\";
else if (DATA_REG_P (operands[3]))
return \"move%.w %1,%3\;ext%.l %3\;add%.l %3,%0\";
else if (DATA_REG_P (operands[0]))
else if (ADDRESS_REG_P (operands[3]))
return \"move%.w %1,%3\;add%.l %3,%0\";
else
return \"move%.l %0,%3\;add%.w %1,%3\;mov%.l %3,%0\";
return \"move%.w %1,%3\;ext%.l %3\;add%.l %3,%0\";
} ")
(define_insn "adddi_dilshr32"
......@@ -2077,10 +2093,10 @@
} ")
(define_insn "adddi3"
[(set (match_operand:DI 0 "general_operand" "=d,<,d,o<>")
(plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0")
(match_operand:DI 2 "general_operand" "d,<,*ao>,d")))
(clobber (match_scratch:SI 3 "=X,X,&d,&d"))]
[(set (match_operand:DI 0 "general_operand" "=<,o<>,d,d,d")
(plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0,0")
(match_operand:DI 2 "general_operand" "<,d,o>,d,a")))
(clobber (match_scratch:SI 3 "=X,&d,&d,X,&d"))]
""
"*
{
......@@ -2625,23 +2641,21 @@
;; subtract instructions
(define_insn "subdi_sexthishl32"
[(set (match_operand:DI 0 "general_operand" "=o,d,a")
(minus:DI (match_operand:DI 1 "general_operand" "0,0,0")
(ashift:DI (sign_extend:DI (match_operand:HI 2 "general_operand" "rm,rm,rm"))
[(set (match_operand:DI 0 "general_operand" "=o,a,*d,*d")
(minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0")
(ashift:DI (sign_extend:DI (match_operand:HI 2 "general_operand" "rm,rm,rm,rm"))
(const_int 32))))
(clobber (match_scratch:SI 3 "=&d*a,a*d,X"))]
(clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
""
"*
{
CC_STATUS_INIT;
if (ADDRESS_REG_P (operands[0]))
return \"sub%.w %2,%0\";
else if (DATA_REG_P (operands[3]))
return \"move%.w %2,%3\;ext%.l %3\;sub%.l %3,%0\";
else if (DATA_REG_P (operands[0]))
else if (ADDRESS_REG_P (operands[3]))
return \"move%.w %2,%3\;sub%.l %3,%0\";
else
return \"move%.l %0,%3\;sub%.w %2,%3\;mov%.l %3,%0\";
return \"move%.w %2,%3\;ext%.l %3\;sub%.l %3,%0\";
} ")
(define_insn "subdi_dishl32"
......@@ -2661,10 +2675,10 @@
} ")
(define_insn "subdi3"
[(set (match_operand:DI 0 "general_operand" "=d,<,d,o<>")
(minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0")
(match_operand:DI 2 "general_operand" "d,<,*ao>,d")))
(clobber (match_scratch:SI 3 "=X,X,&d,&d"))]
[(set (match_operand:DI 0 "general_operand" "=<,o<>,d,d,d")
(minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0,0")
(match_operand:DI 2 "general_operand" "<,d,o>,d,a")))
(clobber (match_scratch:SI 3 "=X,&d,&d,X,&d"))]
""
"*
{
......@@ -3755,12 +3769,12 @@
;; negation instructions
(define_insn "negdi2"
[(set (match_operand:DI 0 "general_operand" "=d*ao,<")
(neg:DI (match_operand:DI 1 "general_operand" "0,0")))]
[(set (match_operand:DI 0 "general_operand" "=<,do,!*a")
(neg:DI (match_operand:DI 1 "general_operand" "0,0,0")))]
""
"*
{
if (which_alternative == 1)
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);
......@@ -4107,23 +4121,35 @@
} ")
(define_insn "ashldi_sexthi"
[(set (match_operand:DI 0 "register_operand" "=*da")
(ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm"))
(const_int 32)))]
[(set (match_operand:DI 0 "general_operand" "=m,a*d")
(ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm,rm"))
(const_int 32)))
(clobber (match_scratch:SI 2 "=a,X"))]
""
"*
{
CC_STATUS_INIT;
operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
if (DATA_REG_P (operands[0]))
return \"move%.w %1,%0\;ext%.l %0\;clr%.l %2\";
if (GET_CODE (operands[0]) == MEM)
{
if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
return \"clr%.l %0\;move%.w %1,%2\;move%.l %2,%0\";
else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
return \"move%.w %1,%2\;move%.l %2,%0\;clr%.l %0\";
else
return \"move%.w %1,%0\;sub%.l %2,%2\";
{
operands[3] = adj_offsettable_operand (operands[0], 4);
return \"move%.w %1,%2\;move%.l %2,%0\;clr%.l %3\";
}
}
else if (DATA_REG_P (operands[0]))
return \"move%.w %1,%0\;ext%.l %0\;clr%.l %R0\";
else
return \"move%.w %1,%0\;sub%.l %R0,%R0\";
} ")
(define_insn "ashldi_const32"
[(set (match_operand:DI 0 "general_operand" "=ro,<,>")
(ashift:DI (match_operand:DI 1 "general_operand" "ro,ro,ro")
[(set (match_operand:DI 0 "general_operand" "=rm")
(ashift:DI (match_operand:DI 1 "general_operand" "ro")
(const_int 32)))]
""
"*
......@@ -4133,12 +4159,12 @@
operands[3] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
else
operands[3] = adj_offsettable_operand (operands[1], 4);
if (which_alternative == 1)
return \"clr%.l %0\;move%.l %3,%0\";
if (which_alternative == 2)
return \"move%.l %3,%0\;clr%.l %0\";
if (GET_CODE (operands[0]) == REG)
operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
return \"clr%.l %0\;move%.l %3,%0\";
else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
return \"move%.l %3,%0\;clr%.l %0\";
else
operands[2] = adj_offsettable_operand (operands[0], 4);
if (ADDRESS_REG_P (operands[2]))
......@@ -4197,6 +4223,9 @@
return \"swap %0\;clr%.w %0\";
}")
;; ashift patterns : use lsl instead of asl, because lsl always clears the
;; overflow bit, so we must not set CC_NO_OVERFLOW.
;; On the 68000, this makes faster code in a special case.
(define_insn ""
......@@ -4210,7 +4239,7 @@
CC_STATUS_INIT;
operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16);
return \"asl%.w %2,%0\;swap %0\;clr%.w %0\";
return \"lsl%.w %2,%0\;swap %0\;clr%.w %0\";
}")
(define_insn "ashlsi3"
......@@ -4221,8 +4250,11 @@
"*
{
if (operands[2] == const1_rtx)
{
cc_status.flags = CC_NO_OVERFLOW;
return \"add%.l %0,%0\";
return \"asl%.l %2,%0\";
}
return \"lsl%.l %2,%0\";
}")
(define_insn "ashlhi3"
......@@ -4230,28 +4262,28 @@
(ashift:HI (match_operand:HI 1 "register_operand" "0")
(match_operand:HI 2 "general_operand" "dI")))]
""
"asl%.w %2,%0")
"lsl%.w %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
(ashift:HI (match_dup 0)
(match_operand:HI 1 "general_operand" "dI")))]
""
"asl%.w %1,%0")
"lsl%.w %1,%0")
(define_insn "ashlqi3"
[(set (match_operand:QI 0 "register_operand" "=d")
(ashift:QI (match_operand:QI 1 "register_operand" "0")
(match_operand:QI 2 "general_operand" "dI")))]
""
"asl%.b %2,%0")
"lsl%.b %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
(ashift:QI (match_dup 0)
(match_operand:QI 1 "general_operand" "dI")))]
""
"asl%.b %1,%0")
"lsl%.b %1,%0")
;; On all 68k models, this makes faster code in a special case.
......@@ -5244,12 +5276,25 @@
""
"*
{
CC_STATUS_INIT;
if (which_alternative == 1)
#ifdef MOTOROLA
return \"move%.l %0,%2\;or%.l %0,%2\;jbeq %l1\";
#else
return \"move%.l %0,%2\;or%.l %0,%2\;jeq %l1\";
#endif
if ((cc_prev_status.value1
&& rtx_equal_p (cc_prev_status.value1, operands[0]))
|| (cc_prev_status.value2
&& rtx_equal_p (cc_prev_status.value2, operands[0])))
{
cc_status = cc_prev_status;
#ifdef MOTOROLA
return \"jbeq %l1\";
#else
return \"jeq %l1\";
#endif
}
if (GET_CODE (operands[0]) == REG)
operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
else
......@@ -5277,10 +5322,23 @@
(const_int 0))
(label_ref (match_operand 1 "" ","))
(pc)))
(clobber (match_scratch:SI 2 "=d,"))]
(clobber (match_scratch:SI 2 "=d,X"))]
""
"*
{
if ((cc_prev_status.value1
&& rtx_equal_p (cc_prev_status.value1, operands[0]))
|| (cc_prev_status.value2
&& rtx_equal_p (cc_prev_status.value2, operands[0])))
{
cc_status = cc_prev_status;
#ifdef MOTOROLA
return \"jbne %l1\";
#else
return \"jne %l1\";
#endif
}
CC_STATUS_INIT;
if (GET_CODE (operands[0]) == REG)
operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
else
......@@ -5308,10 +5366,34 @@
""
"*
{
if ((cc_prev_status.value1
&& rtx_equal_p (cc_prev_status.value1, operands[0]))
|| (cc_prev_status.value2
&& rtx_equal_p (cc_prev_status.value2, operands[0])))
{
cc_status = cc_prev_status;
if (cc_status.flags & CC_REVERSED)
{
#ifdef MOTOROLA
return \"tst%.l %0\;jbge %l1\";
return \"jble %l1\";
#else
return \"tst%.l %0\;jge %l1\";
return \"jle %l1\";
#endif
}
else
{
#ifdef MOTOROLA
return \"jbpl %l1\";
#else
return \"jpl %l1\";
#endif
}
}
CC_STATUS_INIT;
#ifdef MOTOROLA
return \"tst%.l %0\;jbpl %l1\";
#else
return \"tst%.l %0\;jpl %l1\";
#endif
} ")
......@@ -5324,6 +5406,30 @@
""
"*
{
if ((cc_prev_status.value1
&& rtx_equal_p (cc_prev_status.value1, operands[0]))
|| (cc_prev_status.value2
&& rtx_equal_p (cc_prev_status.value2, operands[0])))
{
cc_status = cc_prev_status;
if (cc_status.flags & CC_REVERSED)
{
#ifdef MOTOROLA
return \"jbgt %l1\";
#else
return \"jgt %l1\";
#endif
}
else
{
#ifdef MOTOROLA
return \"jbmi %l1\";
#else
return \"jmi %l1\";
#endif
}
}
CC_STATUS_INIT;
#ifdef MOTOROLA
return \"tst%.l %0\;jbmi %l1\";
#else
......@@ -6310,7 +6416,7 @@
&& (DATA_REG_P (operands[0])
|| GET_CODE (operands[0]) == MEM)
/* clr insns on 68000 read before writing.
This isn't so on the 68010, but we have no alternative for it. */
This isn't so on the 68010, but we have no TARGET_68010. */
&& (TARGET_68020
|| !(GET_CODE (operands[0]) == MEM
&& MEM_VOLATILE_P (operands[0]))))
......
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