(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:
parent
2dedbe1f31
commit
935fb2880c
|
@ -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),
|
||||
|
|
Loading…
Reference in New Issue