Commit 31e033e9 by Richard Kenner

(tstdi, cmpdi, addsi_lshrsi_31, ashldi_extsi): New patterns.

(extendqidi2, extendhidi2, extendsidi2): Allow "general_operand" instead
of "register_operand" 0.
(adddid_sexthishl32, subdid_sexthishl32, subdi_dishl32): Likewise.
(adddi_dilshr32): Operand 0 constraint changed from "ro" to "do";
Code generation fixed.
(adddi_mem, subdi_mem): Fixed for "<" and ">" operand 0.
(adddi3, subdi3): Operand 2 constraint changed from "ao" to "*ao"
(ashldi_sexthi, ashrdi_const32): Allow only "register_operand"
instead of "general_operand" 0.
(ash[lr]di_const, ash[lr]di3): Allow also 8 and 16 as shift count.
(subreg1ashrdi_const32): Pattern deleted.
(subreghi1ashrdi_const32, subregsi1ashrdi_const32): New pattern.
(lshrsi_31): New implementation.
(scc0_di, scc_di, beq0_di, bne0_di, bge0_di, blt0_di): New patterns.

From-SVN: r9666
parent ff0a4409
...@@ -280,6 +280,21 @@ ...@@ -280,6 +280,21 @@
;; We don't want to allow a constant operand for test insns because ;; We don't want to allow a constant operand for test insns because
;; (set (cc0) (const_int foo)) has no mode information. Such insns will ;; (set (cc0) (const_int foo)) has no mode information. Such insns will
;; be folded while optimizing anyway. ;; be folded while optimizing anyway.
(define_insn "tstdi"
[(set (cc0)
(match_operand:DI 0 "nonimmediate_operand" "do"))]
""
"*
{
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);
/* Just in case we come here. I hope all tst:DI are combined !!! */
return \"neg%.l %1\;negx%.l %0\;neg%.l %1\;negx%.l %0\";
}")
(define_insn "tstsi" (define_insn "tstsi"
[(set (cc0) [(set (cc0)
(match_operand:SI 0 "nonimmediate_operand" "rm"))] (match_operand:SI 0 "nonimmediate_operand" "rm"))]
...@@ -383,6 +398,25 @@ ...@@ -383,6 +398,25 @@
;; compare instructions. ;; compare instructions.
(define_insn "cmpdi"
[(set (cc0)
;; (compare (match_operand:DI 0 "general_operand" "=&d*a")
;; (compare (match_operand:DI 0 "general_operand" "+&d*a")
;; (compare (match_operand:DI 0 "general_operand" "+d*a")
(compare (match_operand:DI 0 "general_operand" "d*a")
(match_operand:DI 1 "general_operand" "d")))
(clobber (match_scratch:DI 2 "=0"))]
""
"*
{
operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
operands[3] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
if (DATA_REG_P (operands[0]))
return \"sub%.l %3,%2\;subx%.l %1,%0\";
else
return \"exg %/d0,%2\;sub%.l %3,%/d0\;exg %/d0,%0\;subx%.l %1,%/d0\;exg %/d0,%2\";
}")
;; This is the second "hook" for PIC code (in addition to movsi). See ;; This is the second "hook" for PIC code (in addition to movsi). See
;; comment of movsi for a description of PIC handling. ;; comment of movsi for a description of PIC handling.
(define_expand "cmpsi" (define_expand "cmpsi"
...@@ -1368,7 +1402,7 @@ ...@@ -1368,7 +1402,7 @@
;; zero extension instructions ;; zero extension instructions
;; this one is the canonical form for (lshiftrt:DI x 32) ;; this is the canonical form for (lshiftrt:DI x 32)
(define_insn "zero_extendsidi2" (define_insn "zero_extendsidi2"
[(set (match_operand:DI 0 "general_operand" "ro,<,>") [(set (match_operand:DI 0 "general_operand" "ro,<,>")
(zero_extend:DI (match_operand:SI 1 "general_operand" "rm,rm,rm")))] (zero_extend:DI (match_operand:SI 1 "general_operand" "rm,rm,rm")))]
...@@ -1566,7 +1600,7 @@ ...@@ -1566,7 +1600,7 @@
;; sign extension instructions ;; sign extension instructions
(define_insn "extendqidi2" (define_insn "extendqidi2"
[(set (match_operand:DI 0 "register_operand" "=d") [(set (match_operand:DI 0 "general_operand" "=d")
(sign_extend:DI (sign_extend:DI
(match_operand:QI 1 "general_operand" "rm")))] (match_operand:QI 1 "general_operand" "rm")))]
"" ""
...@@ -1581,7 +1615,7 @@ ...@@ -1581,7 +1615,7 @@
}") }")
(define_insn "extendhidi2" (define_insn "extendhidi2"
[(set (match_operand:DI 0 "register_operand" "=d") [(set (match_operand:DI 0 "general_operand" "=d")
(sign_extend:DI (sign_extend:DI
(match_operand:HI 1 "general_operand" "rm")))] (match_operand:HI 1 "general_operand" "rm")))]
"" ""
...@@ -1596,7 +1630,7 @@ ...@@ -1596,7 +1630,7 @@
}") }")
(define_insn "extendsidi2" (define_insn "extendsidi2"
[(set (match_operand:DI 0 "register_operand" "=d") [(set (match_operand:DI 0 "general_operand" "=d")
(sign_extend:DI (sign_extend:DI
(match_operand:SI 1 "general_operand" "rm")))] (match_operand:SI 1 "general_operand" "rm")))]
"" ""
...@@ -1947,7 +1981,7 @@ ...@@ -1947,7 +1981,7 @@
} ") } ")
(define_insn "adddid_sexthishl32" (define_insn "adddid_sexthishl32"
[(set (match_operand:DI 0 "register_operand" "+do") [(set (match_operand:DI 0 "general_operand" "+ro")
(plus:DI (ashift:DI (sign_extend:DI (plus:DI (ashift:DI (sign_extend:DI
(match_operand:HI 1 "general_operand" "rm")) (match_operand:HI 1 "general_operand" "rm"))
(const_int 32)) (const_int 32))
...@@ -1961,7 +1995,10 @@ ...@@ -1961,7 +1995,10 @@
} ") } ")
(define_insn "adddi_dilshr32" (define_insn "adddi_dilshr32"
[(set (match_operand:DI 0 "general_operand" "=ro") [(set (match_operand:DI 0 "general_operand" "=do")
;; (plus:DI (match_operand:DI 2 "general_operand" "%0")
;; (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
;; (const_int 32))))]
(plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro") (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
(const_int 32)) (const_int 32))
(match_operand:DI 2 "general_operand" "0")))] (match_operand:DI 2 "general_operand" "0")))]
...@@ -1970,14 +2007,17 @@ ...@@ -1970,14 +2007,17 @@
{ {
CC_STATUS_INIT; CC_STATUS_INIT;
if (GET_CODE (operands[0]) == REG) if (GET_CODE (operands[0]) == REG)
operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
else else
operands[0] = adj_offsettable_operand (operands[0], 4); operands[2] = adj_offsettable_operand (operands[0], 4);
return \"add%.l %1,%0\"; return \"add%.l %1,%2\;negx%.l %0\;neg%.l %0\";
} ") } ")
(define_insn "adddi_dishl32" (define_insn "adddi_dishl32"
[(set (match_operand:DI 0 "general_operand" "=ro") [(set (match_operand:DI 0 "general_operand" "=ro")
;; (plus:DI (match_operand:DI 2 "general_operand" "%0")
;; (ashift:DI (match_operand:DI 1 "general_operand" "ro")
;; (const_int 32))))]
(plus:DI (ashift:DI (match_operand:DI 1 "general_operand" "ro") (plus:DI (ashift:DI (match_operand:DI 1 "general_operand" "ro")
(const_int 32)) (const_int 32))
(match_operand:DI 2 "general_operand" "0")))] (match_operand:DI 2 "general_operand" "0")))]
...@@ -1993,23 +2033,35 @@ ...@@ -1993,23 +2033,35 @@
} ") } ")
(define_insn "adddi_mem" (define_insn "adddi_mem"
[(set (match_operand:DI 0 "general_operand" "=m") [(set (match_operand:DI 0 "general_operand" "=o,<,>")
(plus:DI (match_operand:DI 1 "general_operand" "%0") (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0")
(match_operand:DI 2 "general_operand" "d"))) (match_operand:DI 2 "general_operand" "d,d,d")))
(clobber (match_scratch:SI 3 "=d"))] (clobber (match_scratch:SI 3 "=d,d,d"))]
"" ""
"* "*
{ {
CC_STATUS_INIT; CC_STATUS_INIT;
operands[1] = adj_offsettable_operand (operands[0], 4);
operands[4] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1); operands[4] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
if (which_alternative == 2)
{
operands[1] = gen_rtx (MEM, SImode,
gen_rtx (PLUS, VOIDmode, XEXP(operands[0], 0),
gen_rtx (CONST_INT, VOIDmode, -8)));
return \"move%.l %0,%3\;add%.l %4,%0\;addx%.l %2,%3\;move%.l %3,%1\";
}
if (which_alternative == 1)
{
operands[1] = XEXP(operands[0], 0);
return \"add%.l %4,%0\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%1\";
}
operands[1] = adj_offsettable_operand (operands[0], 4);
return \"add%.l %4,%1\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%0\"; return \"add%.l %4,%1\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%0\";
} ") } ")
(define_insn "adddi3" (define_insn "adddi3"
[(set (match_operand:DI 0 "general_operand" "=d,d,d,<") [(set (match_operand:DI 0 "general_operand" "=d,d,d,<")
(plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0") (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0")
(match_operand:DI 2 "general_operand" "ao,>,d,<")))] (match_operand:DI 2 "general_operand" "*ao,>,d,<")))]
"" ""
"* "*
{ {
...@@ -2033,6 +2085,39 @@ ...@@ -2033,6 +2085,39 @@
return \"add%.l %3,%1\;negx%.l %0\;neg%.l %0\;add%.l %2,%0\"; return \"add%.l %3,%1\;negx%.l %0\;neg%.l %0\;add%.l %2,%0\";
} ") } ")
(define_insn "addsi_lshrsi_31"
[(set (match_operand:SI 0 "general_operand" "=dm")
(plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "rm")
(const_int 31))
(match_operand:SI 2 "general_operand" "1")))]
""
"*
{
operands[2] = operands[0];
operands[3] = gen_label_rtx();
if (GET_CODE (operands[0]) == MEM)
{
if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
operands[0] = gen_rtx (MEM, SImode, XEXP (XEXP (operands[0], 0), 0));
else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
operands[2] = gen_rtx (MEM, SImode, XEXP (XEXP (operands[0], 0), 0));
}
output_asm_insn (\"mov%.l %1,%0\", operands);
#ifdef MOTOROLA
output_asm_insn (\"jbpl %l3\", operands);
#else
output_asm_insn (\"jpl %l3\", operands);
#endif
#ifndef NO_ADDSUB_Q
output_asm_insn (\"addq%.l %#1,%2\", operands);
#else
output_asm_insn (\"add%.l %#1,%2\", operands);
#endif
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
CODE_LABEL_NUMBER (operands[3]));
return \"\";
}")
;; Note that the middle two alternatives are near-duplicates ;; Note that the middle two alternatives are near-duplicates
;; in order to handle insns generated by reload. ;; in order to handle insns generated by reload.
;; This is needed since they are not themselves reloaded, ;; This is needed since they are not themselves reloaded,
...@@ -2508,7 +2593,7 @@ ...@@ -2508,7 +2593,7 @@
} ") } ")
(define_insn "subdid_sexthishl32" (define_insn "subdid_sexthishl32"
[(set (match_operand:DI 0 "register_operand" "+do") [(set (match_operand:DI 0 "general_operand" "+ro")
(minus:DI (match_dup 0) (minus:DI (match_dup 0)
(ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm")) (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm"))
(const_int 32)))) (const_int 32))))
...@@ -2521,36 +2606,51 @@ ...@@ -2521,36 +2606,51 @@
} ") } ")
(define_insn "subdi_dishl32" (define_insn "subdi_dishl32"
[(set (match_operand:DI 0 "register_operand" "+d") [(set (match_operand:DI 0 "general_operand" "+ro")
(minus:DI (match_dup 0) (minus:DI (match_dup 0)
(ashift:DI (match_operand:DI 1 "register_operand" "d") (ashift:DI (match_operand:DI 1 "general_operand" "ro")
(const_int 32))))] (const_int 32))))]
"" ""
"* "*
{ {
CC_STATUS_INIT; CC_STATUS_INIT;
operands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); if (GET_CODE (operands[1]) == REG)
operands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
else
operands[1] = adj_offsettable_operand (operands[1], 4);
return \"sub%.l %1,%0\"; return \"sub%.l %1,%0\";
} ") } ")
(define_insn "subdi_mem" (define_insn "subdi_mem"
[(set (match_operand:DI 0 "general_operand" "=m") [(set (match_operand:DI 0 "general_operand" "=o,<,>")
(minus:DI (match_operand:DI 1 "general_operand" "0") (minus:DI (match_operand:DI 1 "general_operand" "0,0,0")
(match_operand:DI 2 "general_operand" "d"))) (match_operand:DI 2 "register_operand" "d,d,d")))
(clobber (match_scratch:SI 3 "=d"))] (clobber (match_scratch:SI 3 "=d,d,d"))]
"" ""
"* "*
{ {
CC_STATUS_INIT; CC_STATUS_INIT;
operands[1] = adj_offsettable_operand (operands[0], 4);
operands[4] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1); operands[4] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
if (which_alternative == 2)
{
operands[1] = gen_rtx (MEM, SImode,
gen_rtx (PLUS, VOIDmode, XEXP(operands[0], 0),
gen_rtx (CONST_INT, VOIDmode, -8)));
return \"move%.l %0,%3\;sub%.l %4,%0\;subx%.l %2,%3\;move%.l %3,%1\";
}
if (which_alternative == 1)
{
operands[1] = XEXP(operands[0], 0);
return \"sub%.l %4,%0\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%1\";
}
operands[1] = adj_offsettable_operand (operands[0], 4);
return \"sub%.l %4,%1\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%0\"; return \"sub%.l %4,%1\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%0\";
} ") } ")
(define_insn "subdi3" (define_insn "subdi3"
[(set (match_operand:DI 0 "general_operand" "=d,d,d,<") [(set (match_operand:DI 0 "general_operand" "=d,d,d,<")
(minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0") (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0")
(match_operand:DI 2 "general_operand" "ao,>,d,<")))] (match_operand:DI 2 "general_operand" "*ao,>,d,<")))]
"" ""
"* "*
{ {
...@@ -3929,8 +4029,28 @@ ...@@ -3929,8 +4029,28 @@
;; arithmetic shift instructions ;; arithmetic shift instructions
;; We don't need the shift memory by 1 bit instruction ;; We don't need the shift memory by 1 bit instruction
(define_insn "ashldi_extsi"
[(set (match_operand:DI 0 "general_operand" "=ro")
(ashift:DI
(match_operator:DI 2 "extend_operator"
[(match_operand:SI 1 "general_operand" "rm")])
(const_int 32)))]
""
"*
{
CC_STATUS_INIT;
if (GET_CODE (operands[0]) == REG)
operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
else
operands[2] = adj_offsettable_operand (operands[0], 4);
if (ADDRESS_REG_P (operands[0]))
return \"move%.l %1,%0\;sub%.l %2,%2\";
else
return \"move%.l %1,%0\;clr%.l %2\";
} ")
(define_insn "ashldi_sexthi" (define_insn "ashldi_sexthi"
[(set (match_operand:DI 0 "general_operand" "=*da") [(set (match_operand:DI 0 "register_operand" "=*da")
(ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm")) (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm"))
(const_int 32)))] (const_int 32)))]
"" ""
...@@ -3970,17 +4090,23 @@ ...@@ -3970,17 +4090,23 @@
return \"move%.l %3,%0\;clr%.l %2\"; return \"move%.l %3,%0\;clr%.l %2\";
} ") } ")
;; The predicate below must be general_operand, because ashldi3 allows that
(define_insn "ashldi_const" (define_insn "ashldi_const"
[(set (match_operand:DI 0 "general_operand" "=d") [(set (match_operand:DI 0 "general_operand" "=d")
(ashift:DI (match_operand:DI 1 "general_operand" "0") (ashift:DI (match_operand:DI 1 "general_operand" "0")
(match_operand 2 "const_int_operand" "n")))] (match_operand 2 "const_int_operand" "n")))]
"(INTVAL (operands[2]) == 1 "(INTVAL (operands[2]) == 1
|| INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
|| INTVAL (operands[2]) == 2 || INTVAL (operands[2]) == 3)" || INTVAL (operands[2]) == 2 || INTVAL (operands[2]) == 3)"
"* "*
{ {
operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
if (INTVAL (operands[2]) == 1) if (INTVAL (operands[2]) == 1)
return \"add%.l %1,%1\;addx%.l %0,%0\"; return \"add%.l %1,%1\;addx%.l %0,%0\";
else if (INTVAL (operands[2]) == 8)
return \"rol%.l %#8,%1\;rol%.l %#8,%0\;mov%.b %1,%0\;clr%.b %1\";
else if (INTVAL (operands[2]) == 16)
return \"swap %1\;swap %0\;mov%.w %1,%0\;clr%.w %1\";
else if (INTVAL (operands[2]) == 2) else if (INTVAL (operands[2]) == 2)
return \"add%.l %1,%1\;addx%.l %0,%0\;add%.l %1,%1\;addx%.l %0,%0\"; return \"add%.l %1,%1\;addx%.l %0,%0\;add%.l %1,%1\;addx%.l %0,%0\";
else/* if (INTVAL (operands[2]) == 3)*/ else/* if (INTVAL (operands[2]) == 3)*/
...@@ -3988,14 +4114,15 @@ ...@@ -3988,14 +4114,15 @@
} ") } ")
(define_expand "ashldi3" (define_expand "ashldi3"
[(set (match_operand:DI 0 "general_operand" "=rm") [(set (match_operand:DI 0 "general_operand" "")
(ashift:DI (match_operand:DI 1 "general_operand" "rm") (ashift:DI (match_operand:DI 1 "general_operand" "")
(match_operand 2 "const_int_operand" "n")))] (match_operand 2 "const_int_operand" "")))]
"" ""
" "
{ {
if (GET_CODE (operands[2]) != CONST_INT if (GET_CODE (operands[2]) != CONST_INT
|| (INTVAL (operands[2]) != 1 && INTVAL (operands[2]) != 32 || (INTVAL (operands[2]) != 1 && INTVAL (operands[2]) != 32
&& INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
&& INTVAL (operands[2]) != 2 && INTVAL (operands[2]) != 3)) && INTVAL (operands[2]) != 2 && INTVAL (operands[2]) != 3))
FAIL; FAIL;
} ") } ")
...@@ -4092,7 +4219,19 @@ ...@@ -4092,7 +4219,19 @@
return \"swap %0\;asr%.w %2,%0\;ext%.l %0\"; return \"swap %0\;asr%.w %2,%0\;ext%.l %0\";
}") }")
(define_insn "subreg1ashrdi_const32" (define_insn "subreghi1ashrdi_const32"
[(set (match_operand:HI 0 "general_operand" "=rm")
(subreg:HI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
(const_int 32)) 1))]
""
"*
{
if (GET_CODE (operands[1]) != REG)
operands[1] = adj_offsettable_operand (operands[1], 2);
return \"move%.w %1,%0\";
} ")
(define_insn "subregsi1ashrdi_const32"
[(set (match_operand:SI 0 "general_operand" "=rm") [(set (match_operand:SI 0 "general_operand" "=rm")
(subreg:SI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro") (subreg:SI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
(const_int 32)) 1))] (const_int 32)) 1))]
...@@ -4103,7 +4242,7 @@ ...@@ -4103,7 +4242,7 @@
} ") } ")
(define_insn "ashrdi_const32" (define_insn "ashrdi_const32"
[(set (match_operand:DI 0 "general_operand" "=d") [(set (match_operand:DI 0 "register_operand" "=d")
(ashiftrt:DI (match_operand:DI 1 "general_operand" "ro") (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
(const_int 32)))] (const_int 32)))]
"" ""
...@@ -4136,11 +4275,13 @@ ...@@ -4136,11 +4275,13 @@
return \"move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0\"; return \"move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0\";
} ") } ")
;; The predicate below must be general_operand, because ashrdi3 allows that
(define_insn "ashrdi_const" (define_insn "ashrdi_const"
[(set (match_operand:DI 0 "general_operand" "=d") [(set (match_operand:DI 0 "general_operand" "=d")
(ashiftrt:DI (match_operand:DI 1 "general_operand" "0") (ashiftrt:DI (match_operand:DI 1 "general_operand" "0")
(match_operand 2 "const_int_operand" "n")))] (match_operand 2 "const_int_operand" "n")))]
"(INTVAL (operands[2]) == 1 "(INTVAL (operands[2]) == 1
|| INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
|| INTVAL (operands[2]) == 2 || INTVAL (operands[2]) == 3)" || INTVAL (operands[2]) == 2 || INTVAL (operands[2]) == 3)"
"* "*
{ {
...@@ -4148,6 +4289,10 @@ ...@@ -4148,6 +4289,10 @@
CC_STATUS_INIT; CC_STATUS_INIT;
if (INTVAL (operands[2]) == 1) if (INTVAL (operands[2]) == 1)
return \"asr%.l %#1,%0\;roxr%.l %#1,%1\"; return \"asr%.l %#1,%0\;roxr%.l %#1,%1\";
else if (INTVAL (operands[2]) == 8)
return \"mov%.b %0,%1\;asr%.l %#8,%0\;ror%.l %#8,%1\";
else if (INTVAL (operands[2]) == 16)
return \"mov%.w %0,%1\;clr%.w %0\;swap %1\;ext%.l %0\";
else if (INTVAL (operands[2]) == 2) else if (INTVAL (operands[2]) == 2)
return \"asr%.l %#1,%0\;roxr%.l %#1,%1\;asr%.l %#1,%0\;roxr%.l %#1,%1\"; return \"asr%.l %#1,%0\;roxr%.l %#1,%1\;asr%.l %#1,%0\;roxr%.l %#1,%1\";
else/* if (INTVAL (operands[2]) == 3)*/ else/* if (INTVAL (operands[2]) == 3)*/
...@@ -4155,14 +4300,15 @@ ...@@ -4155,14 +4300,15 @@
} ") } ")
(define_expand "ashrdi3" (define_expand "ashrdi3"
[(set (match_operand:DI 0 "general_operand" "=rm") [(set (match_operand:DI 0 "general_operand" "")
(ashiftrt:DI (match_operand:DI 1 "general_operand" "rm") (ashiftrt:DI (match_operand:DI 1 "general_operand" "")
(match_operand 2 "const_int_operand" "n")))] (match_operand 2 "const_int_operand" "")))]
"" ""
" "
{ {
if (GET_CODE (operands[2]) != CONST_INT if (GET_CODE (operands[2]) != CONST_INT
|| (INTVAL (operands[2]) != 1 && INTVAL (operands[2]) != 32 || (INTVAL (operands[2]) != 1 && INTVAL (operands[2]) != 32
&& INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
&& INTVAL (operands[2]) != 2 && INTVAL (operands[2]) != 3)) && INTVAL (operands[2]) != 2 && INTVAL (operands[2]) != 3))
FAIL; FAIL;
} ") } ")
...@@ -4204,6 +4350,36 @@ ...@@ -4204,6 +4350,36 @@
;; logical shift instructions ;; logical shift instructions
(define_insn ""
[(set (cc0)
(subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
(const_int 32)) 1))
(set (match_operand:SI 1 "general_operand" "=dm")
(subreg:SI (lshiftrt:DI (match_operand:DI 2 "general_operand" "0")
(const_int 32)) 1))]
""
"*
{
return \"move%.l %0,%1\";
} ")
(define_insn ""
[(set (cc0)
(subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
(const_int 32)) 0))
(set (match_operand:DI 1 "general_operand" "=do")
(lshiftrt:DI (match_operand:DI 2 "general_operand" "0")
(const_int 32)))]
""
"*
{
if (GET_CODE (operands[1]) == REG)
operands[2] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
else
operands[2] = adj_offsettable_operand (operands[1], 4);
return \"move%.l %0,%2\;clr%.l %1\";
} ")
(define_insn "subreg1lshrdi_const32" (define_insn "subreg1lshrdi_const32"
[(set (match_operand:SI 0 "general_operand" "=rm") [(set (match_operand:SI 0 "general_operand" "=rm")
(subreg:SI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro") (subreg:SI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
...@@ -4240,11 +4416,13 @@ ...@@ -4240,11 +4416,13 @@
return \"move%.l %1,%2\;clr%.l %0\"; return \"move%.l %1,%2\;clr%.l %0\";
} ") } ")
;; The predicate below must be general_operand, because lshrdi3 allows that
(define_insn "lshrdi_const" (define_insn "lshrdi_const"
[(set (match_operand:DI 0 "general_operand" "=d") [(set (match_operand:DI 0 "general_operand" "=d")
(lshiftrt:DI (match_operand:DI 1 "general_operand" "0") (lshiftrt:DI (match_operand:DI 1 "general_operand" "0")
(match_operand 2 "const_int_operand" "n")))] (match_operand 2 "const_int_operand" "n")))]
"(INTVAL (operands[2]) == 1 "(INTVAL (operands[2]) == 1
|| INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
|| INTVAL (operands[2]) == 2 || INTVAL (operands[2]) == 3)" || INTVAL (operands[2]) == 2 || INTVAL (operands[2]) == 3)"
"* "*
{ {
...@@ -4252,6 +4430,10 @@ ...@@ -4252,6 +4430,10 @@
operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
if (INTVAL (operands[2]) == 1) if (INTVAL (operands[2]) == 1)
return \"lsr%.l %#1,%0\;roxr%.l %#1,%1\"; return \"lsr%.l %#1,%0\;roxr%.l %#1,%1\";
else if (INTVAL (operands[2]) == 8)
return \"mov%.b %0,%1\;lsr%.l %#8,%0\;ror%.l %#8,%1\";
else if (INTVAL (operands[2]) == 16)
return \"mov%.w %0,%1\;clr%.w %0\;swap %1\;swap %0\";
else if (INTVAL (operands[2]) == 2) else if (INTVAL (operands[2]) == 2)
return \"lsr%.l %#1,%0\;roxr%.l %#1,%1\;lsr%.l %#1,%0\;roxr%.l %#1,%1\"; return \"lsr%.l %#1,%0\;roxr%.l %#1,%1\;lsr%.l %#1,%0\;roxr%.l %#1,%1\";
else /*if (INTVAL (operands[2]) == 3)*/ else /*if (INTVAL (operands[2]) == 3)*/
...@@ -4259,14 +4441,15 @@ ...@@ -4259,14 +4441,15 @@
} ") } ")
(define_expand "lshrdi3" (define_expand "lshrdi3"
[(set (match_operand:DI 0 "general_operand" "=rm") [(set (match_operand:DI 0 "general_operand" "")
(lshiftrt:DI (match_operand:DI 1 "general_operand" "rm") (lshiftrt:DI (match_operand:DI 1 "general_operand" "")
(match_operand 2 "const_int_operand" "n")))] (match_operand 2 "const_int_operand" "")))]
"" ""
" "
{ {
if (GET_CODE (operands[2]) != CONST_INT if (GET_CODE (operands[2]) != CONST_INT
|| (INTVAL (operands[2]) != 1 && INTVAL (operands[2]) != 32 || (INTVAL (operands[2]) != 1 && INTVAL (operands[2]) != 32
&& INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
&& INTVAL (operands[2]) != 2 && INTVAL (operands[2]) != 3)) && INTVAL (operands[2]) != 2 && INTVAL (operands[2]) != 3))
FAIL; FAIL;
} ") } ")
...@@ -4280,11 +4463,7 @@ ...@@ -4280,11 +4463,7 @@
"" ""
"* "*
{ {
#if defined(MOTOROLA) && !defined(CRDS) return \"add%.l %0,%0\;subx%.l %0,%0\;neg%.l %0\";
return \"roxl%.l %#1,%0\;moveq%.l %#0,%d0\;roxl%.l %#1,%0\";
#else
return \"roxl%.l %#1,%0\;moveq %#0,%d0\;roxl%.l %#1,%0\";
#endif
}") }")
;; On all 68k models, this makes faster code in a special case. ;; On all 68k models, this makes faster code in a special case.
...@@ -4854,6 +5033,27 @@ ...@@ -4854,6 +5033,27 @@
return \"bftst %0{%b2:%b1}\"; return \"bftst %0{%b2:%b1}\";
}") }")
(define_insn "scc0_di"
[(set (match_operand:QI 0 "general_operand" "=dm")
(match_operator 1 "valid_dbcc_comparison_p"
[(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))]
""
"*
{
return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]);
} ")
(define_insn "scc_di"
[(set (match_operand:QI 0 "general_operand" "=dm,dm")
(match_operator 1 "valid_dbcc_comparison_p"
[(match_operand:DI 2 "general_operand" "ro,r")
(match_operand:DI 3 "general_operand" "r,ro")]))]
""
"*
{
return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
} ")
(define_insn "seq" (define_insn "seq"
[(set (match_operand:QI 0 "general_operand" "=d") [(set (match_operand:QI 0 "general_operand" "=d")
(eq:QI (cc0) (const_int 0)))] (eq:QI (cc0) (const_int 0)))]
...@@ -4934,6 +5134,75 @@ ...@@ -4934,6 +5134,75 @@
;; Basic conditional jump instructions. ;; Basic conditional jump instructions.
(define_insn "beq0_di"
[(set (pc)
(if_then_else (eq (match_operand:DI 0 "general_operand" "d*ao,<>")
(const_int 0))
(label_ref (match_operand 1 "" ","))
(pc)))
(clobber (match_scratch:SI 2 "=d,d"))]
""
"*
{
if (which_alternative == 1)
return \"move%.l %0,%2\;or%.l %0,%2\;jbeq %l1\";
if (GET_CODE (operands[0]) == REG)
operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
else
operands[3] = adj_offsettable_operand (operands[0], 4);
if (! ADDRESS_REG_P (operands[0]))
return \"move%.l %0,%2\;or%.l %3,%2\;jbeq %l1\";
operands[4] = gen_label_rtx();
output_asm_insn (\"tst%.l %0\;jbne %l4\;tst%.l %3\;jbeq %l1\", operands);
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
CODE_LABEL_NUMBER (operands[4]));
return \"\";
} ")
(define_insn "bne0_di"
[(set (pc)
(if_then_else (ne (match_operand:DI 0 "general_operand" "do,*a")
(const_int 0))
(label_ref (match_operand 1 "" ","))
(pc)))
(clobber (match_scratch:SI 2 "=d,"))]
""
"*
{
if (GET_CODE (operands[0]) == REG)
operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
else
operands[3] = adj_offsettable_operand (operands[0], 4);
if (ADDRESS_REG_P (operands[0]))
return \"tst%.l %0\;jbne %l1\;tst%.l %3\;jbne %l1\";
else
return \"move%.l %0,%2\;or%.l %3,%2\;jbne %l1\";
} ")
(define_insn "bge0_di"
[(set (pc)
(if_then_else (ge (match_operand:DI 0 "general_operand" "ro")
(const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))]
""
"*
{
return \"tst%.l %0\;jbge %l1\";
} ")
(define_insn "blt0_di"
[(set (pc)
(if_then_else (lt (match_operand:DI 0 "general_operand" "ro")
(const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))]
""
"*
{
return \"tst%.l %0\;jbmi %l1\";
} ")
(define_insn "beq" (define_insn "beq"
[(set (pc) [(set (pc)
(if_then_else (eq (cc0) (if_then_else (eq (cc0)
......
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