From 935fb2880ccd5cc9f91d3984faaa914065843f7e Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Mon, 15 Apr 1996 08:21:03 -0400 Subject: [PATCH] (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 --- gcc/config/m68k/m68k.md | 390 +++++++++++++++++++++++++--------------- 1 file 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 ,Dr:Dq; ;;- divu.l ,Dr:Dq; muls.l ,Dr:Dq; mulu.l ,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), -- 2.30.2