(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
This commit is contained in:
Richard Kenner 1996-04-15 08:21:03 -04:00
parent 2dedbe1f31
commit 935fb2880c
1 changed files with 249 additions and 143 deletions

View File

@ -37,7 +37,7 @@
;;- 'd' one of the data registers can be used.
;;- 'f' one of the m68881 registers can be used
;;- 'r' either a data or an address register can be used.
;;- 'x' if one of the Sun FPA registers
;;- 'x' if one of the Sun FPA registers
;;- 'y' if one of the Low Sun FPA registers (fpa0-fpa15).
;;- Immediate Floating point operator constraints
@ -96,12 +96,11 @@
;;- Information about 68060 port.
;;- The 68060 executes all 68030 and 68881/2 instructions, but some must
;;- be emulated in software by the OS. It is faster to avoid these
;;- instructions and issue a library call rather than trapping into
;;- be emulated in software by the OS. It is faster to avoid these
;;- 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
[(set (cc0)
(match_operand:DI 0 "nonimmediate_operand" "d"))
(clobber (match_dup 1))])]
""
"operands[1] = gen_reg_rtx (DImode);")
(define_insn ""
(define_insn "tstdi"
[(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"))]
""
"*
{
cc_status.flags |= CC_REVERSED;
return \"neg%.l %R0\;negx%.l %0\";
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"
@ -347,7 +359,7 @@
(match_operand:QI 0 "nonimmediate_operand" "dm"))]
""
"tst%.b %0")
(define_expand "tstsf"
[(set (cc0)
(match_operand:SF 0 "general_operand" ""))]
@ -449,9 +461,9 @@
""
"
{
if (flag_pic && symbolic_operand (operands[1], SImode))
if (flag_pic && symbolic_operand (operands[1], SImode))
{
/* The source is an address which requires PIC relocation.
/* The source is an address which requires PIC relocation.
Call legitimize_pic_address with the source, mode, and a relocation
register (a new pseudo, or the final destination if reload_in_progress
is set). Then fall through normally */
@ -721,7 +733,7 @@
{
operands[0] = adj_offsettable_operand (operands[0],
INTVAL (operands[1]) / 8);
operands[1] = gen_rtx (CONST_INT, VOIDmode,
operands[1] = gen_rtx (CONST_INT, VOIDmode,
7 - INTVAL (operands[1]) % 8);
return output_btst (operands, operands[1], operands[0], insn, 7);
}
@ -757,12 +769,12 @@
;; Special case of fullword move when source is zero.
;; The reason this is special is to avoid loading a zero
;; into a data reg with moveq in order to store it elsewhere.
(define_insn "movsi_const0"
[(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])))"
"*
@ -779,7 +791,7 @@
return \"clr%.l %0\";
}")
;; General case of fullword move.
;; General case of fullword move.
;;
;; This is the main "hook" for PIC code. When generating
;; PIC, movsi is responsible for determining when the source address
@ -787,16 +799,16 @@
;; to perform the actual relocation.
;;
;; In both the PIC and non-PIC cases the patterns generated will
;; matched by the next define_insn.
;; matched by the next define_insn.
(define_expand "movsi"
[(set (match_operand:SI 0 "general_operand" "")
(match_operand:SI 1 "general_operand" ""))]
""
"
{
if (flag_pic && symbolic_operand (operands[1], SImode))
if (flag_pic && symbolic_operand (operands[1], SImode))
{
/* The source is an address which requires PIC relocation.
/* The source is an address which requires PIC relocation.
Call legitimize_pic_address with the source, mode, and a relocation
register (a new pseudo, or the final destination if reload_in_progress
is set). Then fall through normally */
@ -819,7 +831,7 @@
"*
{
if (which_alternative == 3)
return \"fpmove%.l %x1,fpa0\;fpmove%.l fpa0,%x0\";
return \"fpmove%.l %x1,fpa0\;fpmove%.l fpa0,%x0\";
if (FPA_REG_P (operands[1]) || FPA_REG_P (operands[0]))
return \"fpmove%.l %x1,%x0\";
if (GET_CODE (operands[1]) == CONST_INT)
@ -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"))]
""
"*
{
@ -1000,7 +1012,7 @@
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)
{
@ -1015,7 +1027,7 @@
{
/* 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,
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]))
{
@ -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 (TARGET_68020)
return \"move%.l %2,%3\;add%.l %1,%3\;smi %0\;extb%.l %0\";
if (GET_CODE (operands[1]) == REG
&& REGNO (operands[1]) == REGNO (operands[3]))
output_asm_insn (\"add%.l %2,%3\", operands);
else
return \"move%.l %2,%3\;add%.l %1,%3\;smi %0\;ext%.w %0\;ext%.l %0\";
output_asm_insn (\"move%.l %2,%3\;add%.l %1,%3\", operands);
if (TARGET_68020)
return \"smi %0\;extb%.l %0\";
else
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"))]
""
"*
{
@ -2230,7 +2246,7 @@
if (INTVAL (operands[2]) > 8
&& INTVAL (operands[2]) <= 16
&& ADDRESS_REG_P (operands[0])
&& TARGET_68020)
&& TARGET_68020)
{
operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8);
return \"addq%.w %#8,%0\;addq%.w %2,%0\";
@ -2238,9 +2254,9 @@
if (INTVAL (operands[2]) < -8
&& INTVAL (operands[2]) >= -16
&& ADDRESS_REG_P (operands[0])
&& TARGET_68020)
&& TARGET_68020)
{
operands[2] = gen_rtx (CONST_INT, VOIDmode,
operands[2] = gen_rtx (CONST_INT, VOIDmode,
- INTVAL (operands[2]) - 8);
return \"subq%.w %#8,%0\;subq%.w %2,%0\";
}
@ -2296,7 +2312,7 @@
if (INTVAL (operands[2]) > 8
&& INTVAL (operands[2]) <= 16
&& ADDRESS_REG_P (operands[0])
&& TARGET_68020)
&& TARGET_68020)
{
operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8);
return \"addq%.w %#8,%0\;addq%.w %2,%0\";
@ -2304,9 +2320,9 @@
if (INTVAL (operands[2]) < -8
&& INTVAL (operands[2]) >= -16
&& ADDRESS_REG_P (operands[0])
&& TARGET_68020)
&& TARGET_68020)
{
operands[2] = gen_rtx (CONST_INT, VOIDmode,
operands[2] = gen_rtx (CONST_INT, VOIDmode,
- INTVAL (operands[2]) - 8);
return \"subq%.w %#8,%0\;subq%.w %2,%0\";
}
@ -2356,7 +2372,7 @@
if (INTVAL (operands[1]) > 8
&& INTVAL (operands[1]) <= 16
&& ADDRESS_REG_P (operands[0])
&& TARGET_68020)
&& TARGET_68020)
{
operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8);
return \"addq%.w %#8,%0\;addq%.w %1,%0\";
@ -2364,9 +2380,9 @@
if (INTVAL (operands[1]) < -8
&& INTVAL (operands[1]) >= -16
&& ADDRESS_REG_P (operands[0])
&& TARGET_68020)
&& TARGET_68020)
{
operands[1] = gen_rtx (CONST_INT, VOIDmode,
operands[1] = gen_rtx (CONST_INT, VOIDmode,
- INTVAL (operands[1]) - 8);
return \"subq%.w %#8,%0\;subq%.w %1,%0\";
}
@ -2410,7 +2426,7 @@
if (INTVAL (operands[1]) > 8
&& INTVAL (operands[1]) <= 16
&& ADDRESS_REG_P (operands[0])
&& TARGET_68020)
&& TARGET_68020)
{
operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8);
return \"addq%.w %#8,%0\;addq%.w %1,%0\";
@ -2418,9 +2434,9 @@
if (INTVAL (operands[1]) < -8
&& INTVAL (operands[1]) >= -16
&& ADDRESS_REG_P (operands[0])
&& TARGET_68020)
&& TARGET_68020)
{
operands[1] = gen_rtx (CONST_INT, VOIDmode,
operands[1] = gen_rtx (CONST_INT, VOIDmode,
- INTVAL (operands[1]) - 8);
return \"subq%.w %#8,%0\;subq%.w %1,%0\";
}
@ -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"))]
""
"*
{
@ -3511,7 +3525,7 @@
&& (INTVAL (operands[2]) | 0xffff) == 0xffffffff
&& (DATA_REG_P (operands[0])
|| offsettable_memref_p (operands[0])))
{
{
if (GET_CODE (operands[0]) != REG)
operands[0] = adj_offsettable_operand (operands[0], 2);
operands[2] = gen_rtx (CONST_INT, VOIDmode,
@ -3526,7 +3540,7 @@
&& (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
&& (DATA_REG_P (operands[0])
|| offsettable_memref_p (operands[0])))
{
{
if (DATA_REG_P (operands[0]))
{
operands[1] = gen_rtx (CONST_INT, VOIDmode, logval);
@ -3599,7 +3613,7 @@
&& INTVAL (operands[2]) >> 16 == 0
&& (DATA_REG_P (operands[0])
|| offsettable_memref_p (operands[0])))
{
{
if (GET_CODE (operands[0]) != REG)
operands[0] = adj_offsettable_operand (operands[0], 2);
/* Do not delete a following tstl %0 insn; that would be incorrect. */
@ -3610,7 +3624,7 @@
&& (logval = exact_log2 (INTVAL (operands[2]))) >= 0
&& (DATA_REG_P (operands[0])
|| offsettable_memref_p (operands[0])))
{
{
if (DATA_REG_P (operands[0]))
{
operands[1] = gen_rtx (CONST_INT, VOIDmode, logval);
@ -3699,7 +3713,7 @@
if (GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) >> 16 == 0
&& (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0])))
{
{
if (! DATA_REG_P (operands[0]))
operands[0] = adj_offsettable_operand (operands[0], 2);
/* Do not delete a following tstl %0 insn; that would be incorrect. */
@ -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);
@ -3875,7 +3889,7 @@
if (result != target)
emit_move_insn (result, target);
emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
operand_subword_force (operands[1], 1, DFmode));
@ -4004,7 +4018,7 @@
if (result != target)
emit_move_insn (result, target);
emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
operand_subword_force (operands[1], 1, DFmode));
@ -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
{
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 %2,%2\";
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)
return \"add%.l %0,%0\";
return \"asl%.l %2,%0\";
{
cc_status.flags = CC_NO_OVERFLOW;
return \"add%.l %0,%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.
@ -5089,7 +5121,7 @@
{
if (operands[1] == const1_rtx
&& GET_CODE (operands[2]) == CONST_INT)
{
{
int width = GET_CODE (operands[0]) == REG ? 31 : 7;
return output_btst (operands,
gen_rtx (CONST_INT, VOIDmode,
@ -5105,7 +5137,7 @@
return \"bftst %0{%b2:%b1}\";
}")
;;; now handle the register cases
(define_insn ""
[(set (cc0)
@ -5117,7 +5149,7 @@
{
if (operands[1] == const1_rtx
&& GET_CODE (operands[2]) == CONST_INT)
{
{
int width = GET_CODE (operands[0]) == REG ? 31 : 7;
return output_btst (operands,
gen_rtx (CONST_INT, VOIDmode,
@ -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
@ -5905,10 +6011,10 @@
;; For PIC calls, in order to be able to support
;; dynamic linker LAZY BINDING, all the procedure calls need to go
;; dynamic linker LAZY BINDING, all the procedure calls need to go
;; through the PLT (Procedure Linkage Table) section in PIC mode.
;;
;; PIC calls are handled by loading the address of the function into a
;; PIC calls are handled by loading the address of the function into a
;; register (via movsi), then emitting a register indirect call using
;; the "jsr" function call syntax.
;;
@ -5919,26 +6025,26 @@
;; We have different patterns for PIC calls and non-PIC calls. The
;; different patterns are only used to choose the right syntax.
;;
;; The svr4 m68k assembler recognizes this syntax: `bsr FUNC@PLTPC' and it
;; will create the correct relocation entry (R_68K_PLT32) for `FUNC',
;; The svr4 m68k assembler recognizes this syntax: `bsr FUNC@PLTPC' and it
;; will create the correct relocation entry (R_68K_PLT32) for `FUNC',
;; that tells the linker editor to create an entry for `FUNC' in PLT
;; section at link time. However, all global objects reference are still
;; done by using `OBJ@GOT'. So, the goal here is to output the function
;; call operand as `FUNC@PLTPC', but output object operand as `OBJ@GOT'.
;; done by using `OBJ@GOT'. So, the goal here is to output the function
;; call operand as `FUNC@PLTPC', but output object operand as `OBJ@GOT'.
;; We need to have a way to differentiate these two different operands.
;;
;; The strategy I use here is to use SYMBOL_REF_FLAG to differentiate
;; The strategy I use here is to use SYMBOL_REF_FLAG to differentiate
;; these two different operands. The macro LEGITIMATE_PIC_OPERAND_P needs
;; to be changed to recognize function calls symbol_ref operand as a valid
;; PIC operand (by checking whether SYMBOL_REF_FLAG is set). This will
;; avoid the compiler to load this symbol_ref operand into a register.
;; Remember, the operand "foo@PLTPC" cannot be called via jsr directly
;; to be changed to recognize function calls symbol_ref operand as a valid
;; PIC operand (by checking whether SYMBOL_REF_FLAG is set). This will
;; avoid the compiler to load this symbol_ref operand into a register.
;; Remember, the operand "foo@PLTPC" cannot be called via jsr directly
;; since the value is a PC relative offset, not a real address.
;;
;; All global objects are treated in the similar way as in SUN3. The only
;; difference is: on m68k svr4, the reference of such global object needs
;; All global objects are treated in the similar way as in SUN3. The only
;; difference is: on m68k svr4, the reference of such global object needs
;; to end with a suffix "@GOT" so the assembler and linker know to create
;; an entry for it in GOT (Global Offset Table) section. This is done in
;; an entry for it in GOT (Global Offset Table) section. This is done in
;; m68k.c.
;; Call subroutine with no return value.
@ -5964,7 +6070,7 @@
"*
#if defined (MOTOROLA) && !defined (USE_GAS)
#ifdef MOTOROLA_BSR
if (GET_CODE (operands[0]) == MEM
if (GET_CODE (operands[0]) == MEM
&& GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
return \"bsr %0\";
#endif
@ -5982,7 +6088,7 @@
"flag_pic"
"*
if (GET_CODE (operands[0]) == MEM
if (GET_CODE (operands[0]) == MEM
&& GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
#ifdef MOTOROLA
#ifdef HPUX_ASM
@ -6027,7 +6133,7 @@
"*
#if defined (MOTOROLA) && !defined (USE_GAS)
#ifdef MOTOROLA_BSR
if (GET_CODE (operands[1]) == MEM
if (GET_CODE (operands[1]) == MEM
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
return \"bsr %1\";
#endif
@ -6045,7 +6151,7 @@
;; Operand 2 not really used on the m68000.
"flag_pic"
"*
if (GET_CODE (operands[1]) == MEM
if (GET_CODE (operands[1]) == MEM
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
#ifdef MOTOROLA
#ifdef HPUX_ASM
@ -6219,7 +6325,7 @@
output_asm_insn (\"addq%.w %1,%0\", xoperands);
else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020)
{
xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
INTVAL (xoperands[1]) - 8);
output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands);
}
@ -6256,7 +6362,7 @@
output_asm_insn (\"addq%.w %1,%0\", xoperands);
else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020)
{
xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
INTVAL (xoperands[1]) - 8);
output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands);
}
@ -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]))))
@ -6624,7 +6730,7 @@
}
return \"fmove%.d %f1,%0\";
}")
(define_insn "truncxfsf2"
[(set (match_operand:SF 0 "general_operand" "=dm")
(float_truncate:SF
@ -6835,7 +6941,7 @@
if (result != target)
emit_move_insn (result, target);
emit_move_insn (operand_subword (operands[0], 1, 1, XFmode),
operand_subword_force (operands[1], 1, XFmode));
emit_move_insn (operand_subword (operands[0], 2, 1, XFmode),
@ -6884,7 +6990,7 @@
if (result != target)
emit_move_insn (result, target);
emit_move_insn (operand_subword (operands[0], 1, 1, XFmode),
operand_subword_force (operands[1], 1, XFmode));
emit_move_insn (operand_subword (operands[0], 2, 1, XFmode),