summaryrefslogtreecommitdiff
path: root/gcc/config/m68k/m68k.md
diff options
context:
space:
mode:
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>1996-04-15 12:21:03 +0000
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>1996-04-15 12:21:03 +0000
commit3f6dfb8716a6355c23340b6f63aa29501fa143ad (patch)
treeba9e67dee849ed5315f0a1fbfa90cbb8a0d3a9ab /gcc/config/m68k/m68k.md
parent5bbe93b9caa9d82af163465cffc63b83df2e1219 (diff)
downloadgcc-3f6dfb8716a6355c23340b6f63aa29501fa143ad.tar.gz
(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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@11783 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/m68k/m68k.md')
-rw-r--r--gcc/config/m68k/m68k.md390
1 files changed, 248 insertions, 142 deletions
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 29191038ec4..78deaf71586 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -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 (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"))]
""
"*
{
@@ -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),