X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=gcc%2Fconfig%2Fm68hc11%2Fm68hc11.md;h=0d40278cebb9ae6455f9e6d626a8e4bba24ff99f;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=3ba35d0fd237e42e77c5cb09bf8a2fd3abcb511f;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/gcc/config/m68hc11/m68hc11.md b/gcc/config/m68hc11/m68hc11.md index 3ba35d0f..0d40278c 100644 --- a/gcc/config/m68hc11/m68hc11.md +++ b/gcc/config/m68hc11/m68hc11.md @@ -1,23 +1,23 @@ ;;- Machine description file for Motorola 68HC11 and 68HC12. -;;- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +;;- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 +;;- Free Software Foundation, Inc. ;;- Contributed by Stephane Carrez (stcarrez@nerim.fr) -;; This file is part of GNU CC. +;; This file is part of GCC. -;; GNU CC is free software; you can redistribute it and/or modify +;; GCC is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) +;; the Free Software Foundation; either version 3, or (at your option) ;; any later version. -;; GNU CC is distributed in the hope that it will be useful, +;; GCC is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU CC; see the file COPYING. If not, write to -;; the Free Software Foundation, 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; along with GCC; see the file COPYING3. If not see +;; . ;; Note: ;; A first 68HC11 port was made by Otto Lind (otto@coactive.com) @@ -66,7 +66,7 @@ ;; Other constraints: ;; ;; Q an operand which is in memory but whose address is constant -;; (ie, a (MEM (SYMBOL_REF x))). This constraint is used by +;; (i.e., a (MEM (SYMBOL_REF x))). This constraint is used by ;; bset/bclr instructions together with linker relaxation. The ;; operand can be translated to a page0 addressing mode if the ;; symbol address is in page0 (0..255). @@ -93,7 +93,7 @@ ;; Operands modifiers: ;; ;; %b Get the low part of the operand (to obtain a QImode) -;; This modified must always be used for QImode operations +;; This modifier must always be used for QImode operations ;; because a correction must be applied when the operand ;; is a soft register (ex: *ZD1). Otherwise, we generate ;; *ZD1 and this is the high part of the register. For other @@ -143,8 +143,13 @@ (A_REGNUM 5) ; A (high part of D) (B_REGNUM 6) ; B (low part of D) (CC_REGNUM 7) ; Condition code register + (SOFT_TMP_REGNUM 10) ; TMP soft register + (SOFT_Z_REGNUM 11) ; Z soft register + (SOFT_XY_REGNUM 12) ; XY soft register ]) +(include "predicates.md") + ;;-------------------------------------------------------------------- ;;- Test ;;-------------------------------------------------------------------- @@ -153,7 +158,7 @@ ;; an auto-inc mode. If we do this, the reload can emit move insns ;; after the test or compare. Such move will set the flags and therefore ;; break the comparison. This can happen if the auto-inc register -;; does not happen to be a hard register (ie, reloading occurs). +;; does not happen to be a hard register (i.e., reloading occurs). ;; An offsetable memory operand should be ok. The 'tst_operand' and ;; 'cmp_operand' predicates take care of this rule. ;; @@ -214,7 +219,7 @@ (set (cc0) (reg:QI D_REGNUM)) (parallel [(set (reg:HI D_REGNUM) (match_dup 1)) (set (match_dup 1) (reg:HI D_REGNUM))])] - "operands[1] = gen_rtx (REG, HImode, REGNO (operands[0]));") + "operands[1] = gen_rtx_REG (HImode, REGNO (operands[0]));") (define_insn "tstqi_1" [(set (cc0) @@ -238,7 +243,7 @@ ;; ;; tstqi_z_used, cmpqi_z_used and cmphi_z_used are patterns generated ;; during the Z register replacement. They are used when an operand -;; uses the Z register as an index register (ie, (MEM:QI (REG:HI Z))). +;; uses the Z register as an index register (i.e., (MEM:QI (REG:HI Z))). ;; In that case, we have to preserve the values of the replacement ;; register (as well as the CC0 since the insns are compare insns). ;; To do this, the replacement register is pushed on the stack and @@ -246,25 +251,19 @@ ;; avoid problems with the flow+cse register pass which are made ;; after Z register replacement. ;; -(define_insn "tstqi_z_used" +(define_insn_and_split "tstqi_z_used" [(set (cc0) (match_operand:QI 0 "tst_operand" "m")) (use (match_operand:HI 1 "hard_reg_operand" "dxy")) - (use (reg:HI 11))] + (use (reg:HI SOFT_Z_REGNUM))] "" - "#") - -(define_split /* "tstqi_z_used" */ - [(set (cc0) - (match_operand:QI 0 "tst_operand" "")) - (use (match_operand:HI 1 "hard_reg_operand" "")) - (use (reg:HI 11))] + "#" "z_replacement_completed == 2" [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 1)) (set (match_dup 1) (match_dup 2)) (set (cc0) (match_dup 0)) (set (match_dup 1) (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))] - "operands[2] = gen_rtx (REG, HImode, SOFT_Z_REGNUM);") + "operands[2] = gen_rtx_REG (HImode, SOFT_Z_REGNUM);") ;;-------------------------------------------------------------------- @@ -299,11 +298,23 @@ [(set (cc0) (compare (match_operand:HI 0 "hard_reg_operand" "") (match_operand:HI 1 "hard_reg_operand" "")))] - "reload_completed" + "TARGET_M6811 + && reload_completed && !(Z_REG_P (operands[0]) || Z_REG_P (operands[1]))" [(set (match_dup 2) (match_dup 1)) (set (cc0) (compare (match_dup 0) (match_dup 2)))] - "operands[2] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM);") + "operands[2] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM);") + +(define_split + [(set (cc0) + (compare (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "hard_reg_operand" "")))] + "0 && TARGET_M6812 + && reload_completed && !(Z_REG_P (operands[0]) || Z_REG_P (operands[1]))" + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 1)) + (set (cc0) + (compare (match_dup 0) (mem:HI (post_inc:HI (reg:HI SP_REGNUM)))))] + "") (define_expand "cmphi" [(set (cc0) @@ -324,7 +335,7 @@ [(set (cc0) (compare (match_operand:HI 0 "tst_operand" "d,?xy,xyd,?xy,d,m,!u,dxy,dxy") - (match_operand:HI 1 "cmp_operand" + (match_operand:HI 1 "general_operand" "i,i,!u,m,m,dxy,dxy,?*d*A,!*w")))] "TARGET_M6812" "* @@ -334,8 +345,10 @@ cc_status.flags |= CC_REVERSED; return \"cp%1\\t%0\"; } + else if (SP_REG_P (operands[1])) + return \"sts\\t2,-sp\n\\tcp%0\\t2,sp+\"; else if (H_REG_P (operands[1])) - return \"#\"; + return \"psh%1\n\\tcp%0\\t2,sp+\"; else return \"cp%0\\t%1\"; }") @@ -343,9 +356,9 @@ (define_insn "cmphi_1_hc11" [(set (cc0) (compare (match_operand:HI 0 "tst_operand" - "dx,y,xyd,?xy,d,m,!u,dxy,dxy") + "dx,y,xyd,?xy,d,m,m,dxy,dxy,?u*z,dxy,*z") (match_operand:HI 1 "cmp_operand" - "i,i,!u,m,m,dxy,dxy,?*d*A,!*w")))] + "i,i,!u,m,m,?xy,d,?*d*A,?u,dxy,!*w,i")))] "TARGET_M6811" "* { @@ -360,27 +373,20 @@ return \"cp%0\\t%1\"; }") -(define_insn "cmphi_z_used" +(define_insn_and_split "cmphi_z_used" [(set (cc0) (compare (match_operand:HI 0 "tst_operand" "dxy,m") - (match_operand:HI 1 "cmp_operand" "m,dxy"))) + (match_operand:HI 1 "cmp_operand" "mi,dxy"))) (use (match_operand:HI 2 "hard_reg_operand" "dxy,dxy")) - (use (reg:HI 11))] + (use (reg:HI SOFT_Z_REGNUM))] "" - "#") - -(define_split /* "cmphi_z_used" */ - [(set (cc0) - (compare (match_operand:HI 0 "tst_operand" "") - (match_operand:HI 1 "cmp_operand" ""))) - (use (match_operand:HI 2 "hard_reg_operand" "")) - (use (reg:HI 11))] + "#" "z_replacement_completed == 2" [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2)) (set (match_dup 2) (match_dup 3)) (set (cc0) (compare (match_dup 0) (match_dup 1))) (set (match_dup 2) (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))] - "operands[3] = gen_rtx (REG, HImode, SOFT_Z_REGNUM);") + "operands[3] = gen_rtx_REG (HImode, SOFT_Z_REGNUM);") ;; ;; 8-bit comparison with address register. @@ -399,7 +405,7 @@ (compare (reg:QI D_REGNUM) (match_dup 1))) (parallel [(set (reg:HI D_REGNUM) (match_dup 3)) (set (match_dup 3) (reg:HI D_REGNUM))])] - "operands[3] = gen_rtx (REG, HImode, REGNO (operands[0]));") + "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));") (define_split [(set (cc0) @@ -409,9 +415,9 @@ [(set (match_dup 3) (match_dup 4)) (set (cc0) (compare (match_dup 0) (match_dup 2)))] - "operands[2] = gen_rtx (REG, QImode, SOFT_TMP_REGNUM); - operands[3] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM); - operands[4] = gen_rtx (REG, HImode, REGNO (operands[1]));") + "operands[2] = gen_rtx_REG (QImode, SOFT_TMP_REGNUM); + operands[3] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM); + operands[4] = gen_rtx_REG (HImode, REGNO (operands[1]));") (define_expand "cmpqi" [(set (cc0) @@ -444,34 +450,27 @@ [(set (cc0) (and:QI (match_operand:QI 0 "tst_operand" "") (match_operand:QI 1 "hard_addr_reg_operand" "")))] - "z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode" + "z_replacement_completed == 2" [(set (match_dup 3) (match_dup 2)) (set (cc0) (and:QI (match_dup 0) (match_dup 4)))] - "operands[2] = gen_rtx (REG, HImode, REGNO (operands[1])); - operands[3] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM); - operands[4] = gen_rtx (REG, QImode, SOFT_TMP_REGNUM);") + "operands[2] = gen_rtx_REG (HImode, REGNO (operands[1])); + operands[3] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM); + operands[4] = gen_rtx_REG (QImode, SOFT_TMP_REGNUM);") -(define_insn "bitcmpqi_z_used" +(define_insn_and_split "bitcmpqi_z_used" [(set (cc0) (and:QI (match_operand:QI 0 "tst_operand" "d,m") (match_operand:QI 1 "cmp_operand" "m,d"))) (use (match_operand:HI 2 "hard_reg_operand" "xy,xy")) - (use (reg:HI 11))] + (use (reg:HI SOFT_Z_REGNUM))] "" - "#") - -(define_split /* "bitcmpqi_z_used" */ - [(set (cc0) - (and:QI (match_operand:QI 0 "tst_operand" "") - (match_operand:QI 1 "cmp_operand" ""))) - (use (match_operand:HI 2 "hard_reg_operand" "")) - (use (reg:HI 11))] + "#" "z_replacement_completed == 2" - [(set (mem:HI (pre_dec:HI (reg:HI 3))) (match_dup 2)) + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2)) (set (match_dup 2) (match_dup 3)) (set (cc0) (and:QI (match_dup 0) (match_dup 1))) - (set (match_dup 2) (mem:HI (post_inc:HI (reg:HI 3))))] - "operands[3] = gen_rtx (REG, HImode, SOFT_Z_REGNUM);") + (set (match_dup 2) (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))] + "operands[3] = gen_rtx_REG (HImode, SOFT_Z_REGNUM);") (define_insn "bitcmphi" [(set (cc0) @@ -541,27 +540,20 @@ return \"cmpb\\t%b0\"; }") -(define_insn "cmpqi_z_used" +(define_insn_and_split "cmpqi_z_used" [(set (cc0) (compare (match_operand:QI 0 "tst_operand" "dxy,m") (match_operand:QI 1 "cmp_operand" "m,dxy"))) (use (match_operand:HI 2 "hard_reg_operand" "dxy,dxy")) - (use (reg:HI 11))] + (use (reg:HI SOFT_Z_REGNUM))] "" - "#") - -(define_split /* cmpqi_z_used */ - [(set (cc0) - (compare (match_operand:QI 0 "tst_operand" "") - (match_operand:QI 1 "cmp_operand" ""))) - (use (match_operand:HI 2 "hard_reg_operand" "")) - (use (reg:HI 11))] + "#" "z_replacement_completed == 2" [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2)) (set (match_dup 2) (match_dup 3)) (set (cc0) (compare (match_dup 0) (match_dup 1))) (set (match_dup 2) (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))] - "operands[3] = gen_rtx (REG, HImode, SOFT_Z_REGNUM);") + "operands[3] = gen_rtx_REG (HImode, SOFT_Z_REGNUM);") ;;-------------------------------------------------------------------- ;;- Move strict_low_part @@ -572,41 +564,29 @@ ;; (strict_low_part ...) information. This is correct for our machine ;; description but not for GCC optimization passes. ;; -(define_insn "movstrictsi" +(define_insn_and_split "movstrictsi" [(set (strict_low_part (match_operand:SI 0 "non_push_operand" "+um,D,D")) (match_operand:SI 1 "general_operand" "D,Dim,uD"))] "" - "#") - -(define_split - [(set (strict_low_part (match_operand:SI 0 "non_push_operand" "")) - (match_operand:SI 1 "general_operand" ""))] + "#" "z_replacement_completed == 2" [(set (match_dup 0) (match_dup 1))] "") -(define_insn "movstricthi" +(define_insn_and_split "movstricthi" [(set (strict_low_part (match_operand:HI 0 "non_push_operand" "+um,dA,dA")) (match_operand:HI 1 "general_operand" "dA,dAim,u"))] "" - "#") - -(define_split - [(set (strict_low_part (match_operand:HI 0 "non_push_operand" "")) - (match_operand:HI 1 "general_operand" ""))] + "#" "z_replacement_completed == 2" [(set (match_dup 0) (match_dup 1))] "") -(define_insn "movstrictqi" +(define_insn_and_split "movstrictqi" [(set (strict_low_part (match_operand:QI 0 "non_push_operand" "+mu,!dA")) (match_operand:QI 1 "general_operand" "d,imudA"))] "" - "#") - -(define_split - [(set (strict_low_part (match_operand:QI 0 "non_push_operand" "")) - (match_operand:QI 1 "general_operand" ""))] + "#" "z_replacement_completed == 2" [(set (match_dup 0) (match_dup 1))] "") @@ -620,7 +600,7 @@ ;; because there is no memory->memory moves. It must be defined with ;; earlyclobber (&) so that it does not appear in the source or destination ;; address. Providing patterns for movdi/movdf allows GCC to generate -;; better code. [Until now, the scratch register is limited to D becuse +;; better code. [Until now, the scratch register is limited to D because ;; otherwise we can run out of registers in the A_REGS class for reload]. ;; ;; For 68HC12, the scratch register is not necessary. To use the same @@ -650,17 +630,26 @@ } ") -(define_insn "movdi_internal" - [(set (match_operand:DI 0 "nonimmediate_operand" "=ou,U,!u,U,m,m,!u") +;; Separate push from normal moves to avoid reloading problems +;; The 'clr' is not able to push on 68HC11 so we really need a scratch. +;; We can also accept more scratch registers. +(define_insn_and_split "*pushdi_internal" + [(set (match_operand:DI 0 "push_operand" "=<,<,<,<") + (match_operand:DI 1 "general_operand" "i,U,m,!u")) + (clobber (match_scratch:HI 2 "=&dA,&d,&d,&dA"))] + "" + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_move (operands[0], operands[1], operands[2]); + DONE;") + +(define_insn_and_split "movdi_internal" + [(set (match_operand:DI 0 "non_push_operand" "=m!u,U,!u,U,m,m,!u") (match_operand:DI 1 "general_operand" "K,iU,iU,!u,mi,!u,!mu")) (clobber (match_scratch:HI 2 "=X,&d,&d,&d,&d,&d,&d"))] "" - "#") - -(define_split - [(set (match_operand:DI 0 "nonimmediate_operand" "") - (match_operand:DI 1 "general_operand" "")) - (clobber (match_scratch:HI 2 ""))] + "#" "reload_completed" [(const_int 0)] "m68hc11_split_move (operands[0], operands[1], operands[2]); @@ -686,17 +675,24 @@ } ") -(define_insn "movdf_internal" - [(set (match_operand:DF 0 "nonimmediate_operand" "=ou,U,!u,U,m,m,!u") - (match_operand:DF 1 "general_operand" "G,iU,iU,!u,mi,!u,!mu")) - (clobber (match_scratch:HI 2 "=X,&d,&d,&d,&d,&d,&d"))] +;; See pushdi_internal +(define_insn_and_split "*pushdf_internal" + [(set (match_operand:DF 0 "push_operand" "=<,<,<,<") + (match_operand:DF 1 "general_operand" "i,U,m,!u")) + (clobber (match_scratch:HI 2 "=&dA,&d,&d,&dA"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_move (operands[0], operands[1], operands[2]); + DONE;") -(define_split - [(set (match_operand:DF 0 "nonimmediate_operand" "") - (match_operand:DF 1 "general_operand" "")) - (clobber (match_scratch:HI 2 ""))] +(define_insn_and_split "movdf_internal" + [(set (match_operand:DF 0 "non_push_operand" "=mu,U,m,!u,U,m,!u") + (match_operand:DF 1 "general_operand" "G,iU,mi,iU,!u,!u,!mu")) + (clobber (match_scratch:HI 2 "=X,&d,&d,&d,&d,&d,&d"))] + "" + "#" "reload_completed" [(const_int 0)] "m68hc11_split_move (operands[0], operands[1], operands[2]); @@ -731,17 +727,23 @@ } ") -(define_insn "movsi_internal" - [(set (match_operand:SI 0 "nonimmediate_operand" "=ou,mu,?D,m,?D,?u,?u,!u,D") - (match_operand:SI 1 "general_operand" "K,imu,im,?D,!u,?D,mi,!u,!D")) - (clobber (match_scratch:HI 2 "=X,&d,X,X,X,X,&d,&d,X"))] +(define_insn_and_split "*pushsi_internal" + [(set (match_operand:SI 0 "push_operand" "=<,<,<,<,<") + (match_operand:SI 1 "general_operand" "!D,i,U,m,!u")) + (clobber (match_scratch:HI 2 "=X,&dA,&d,&d,&dA"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_move (operands[0], operands[1], operands[2]); + DONE;") -(define_split - [(set (match_operand:SI 0 "nonimmediate_operand" "") - (match_operand:SI 1 "general_operand" "")) - (clobber (match_scratch:HI 2 ""))] +(define_insn_and_split "movsi_internal" + [(set (match_operand:SI 0 "nonimmediate_operand" "=mu,mu,?D,m,?D,?u,?u,!u,D") + (match_operand:SI 1 "general_operand" "K,imu,im,?D,!u,?D,mi,!u,!D")) + (clobber (match_scratch:HI 2 "=X,&d,X,X,X,X,&d,&d,X"))] + "" + "#" "reload_completed" [(const_int 0)] "m68hc11_split_move (operands[0], operands[1], operands[2]); @@ -767,17 +769,23 @@ } ") -(define_insn "movsf_internal" - [(set (match_operand:SF 0 "nonimmediate_operand" "=o!u,m,D,m,D,!u,!u,!u,D") +(define_insn_and_split "*pushsf_internal" + [(set (match_operand:SF 0 "push_operand" "=<,<,<,<,<") + (match_operand:SF 1 "general_operand" "!D,i,U,m,!u")) + (clobber (match_scratch:HI 2 "=X,&dA,&d,&d,&dA"))] + "" + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_move (operands[0], operands[1], operands[2]); + DONE;") + +(define_insn_and_split "movsf_internal" + [(set (match_operand:SF 0 "nonimmediate_operand" "=m!u,m,D,m,D,!u,!u,!u,D") (match_operand:SF 1 "general_operand" "G,im,im,D,!u,D,mi,!u,!D")) (clobber (match_scratch:HI 2 "=X,&d,X,X,X,X,&d,&d,X"))] "" - "#") - -(define_split - [(set (match_operand:SF 0 "nonimmediate_operand" "") - (match_operand:SF 1 "general_operand" "")) - (clobber (match_scratch:HI 2 ""))] + "#" "reload_completed" [(const_int 0)] "m68hc11_split_move (operands[0], operands[1], operands[2]); @@ -869,7 +877,7 @@ { rtx insn; - insn = emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); REG_NOTES (insn) = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn)); @@ -877,18 +885,9 @@ } }") -(define_insn "movhi_const0" - [(set (match_operand:HI 0 "non_push_operand" "=d,A,um") - (const_int 0))] - "" - "@ - clra\\n\\tclrb - ld%0\\t#0 - clr\\t%b0\\n\\tclr\\t%h0") - (define_insn "*movhi_68hc12" - [(set (match_operand:HI 0 "nonimmediate_operand" "=U,dAw,U,U,m,!u") - (match_operand:HI 1 "general_operand" "U,rim,dAwi,!u,dAw,riU"))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=U,dAw,dAw,m,U,U,m,!u") + (match_operand:HI 1 "general_operand" "U,dAwim,!u,K,dAwi,!u,dAw,riU"))] "TARGET_M6812" "* { @@ -896,6 +895,15 @@ return \"\"; }") +(define_insn "movhi_const0" + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,A,um") + (const_int 0))] + "TARGET_M6811" + "@ + clra\\n\\tclrb + ld%0\\t#0 + clr\\t%b0\\n\\tclr\\t%h0") + (define_insn "*movhi_m68hc11" [(set (match_operand:HI 0 "nonimmediate_operand" "=dAw,!u,m,m,dAw,!*u") (match_operand:HI 1 "general_operand" "dAwim,dAw,dA,?Aw,!*u,dAw"))] @@ -935,15 +943,15 @@ (define_split [(set (match_operand:QI 0 "hard_addr_reg_operand" "") (match_operand:QI 1 "general_operand" ""))] - "z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode + "z_replacement_completed == 2 && !reg_mentioned_p (operands[0], operands[1]) - && !D_REG_P (operands[1])" + && !(D_REG_P (operands[1]) || Q_REG_P (operands[1]))" [(parallel [(set (reg:HI D_REGNUM) (match_dup 2)) (set (match_dup 2) (reg:HI D_REGNUM))]) (set (reg:QI D_REGNUM) (match_dup 1)) (parallel [(set (reg:HI D_REGNUM) (match_dup 2)) (set (match_dup 2) (reg:HI D_REGNUM))])] - "operands[2] = gen_rtx (REG, HImode, REGNO (operands[0]));") + "operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));") ;; ;; 8-bit operations on address registers. @@ -951,15 +959,15 @@ (define_split [(set (match_operand:QI 0 "nonimmediate_operand" "") (match_operand:QI 1 "hard_addr_reg_operand" ""))] - "z_replacement_completed == 2 && GET_MODE (operands[1]) == QImode + "z_replacement_completed == 2 && !reg_mentioned_p (operands[1], operands[0]) - && !D_REG_P (operands[0])" + && !(D_REG_P (operands[0]) || Q_REG_P (operands[0]))" [(parallel [(set (reg:HI D_REGNUM) (match_dup 2)) (set (match_dup 2) (reg:HI D_REGNUM))]) (set (match_dup 0) (reg:QI D_REGNUM)) (parallel [(set (reg:HI D_REGNUM) (match_dup 2)) (set (match_dup 2) (reg:HI D_REGNUM))])] - "operands[2] = gen_rtx (REG, HImode, REGNO (operands[1]));") + "operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));") (define_insn "*movqi2_push" [(set (match_operand:QI 0 "push_operand" "=<,<") @@ -1009,7 +1017,7 @@ { rtx insn; - insn = emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); REG_NOTES (insn) = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn)); @@ -1111,7 +1119,7 @@ /* Source operand must be in a hard register. */ if (!H_REG_P (src)) { - src = gen_rtx (REG, QImode, REGNO (operands[2])); + src = gen_rtx_REG (QImode, REGNO (operands[2])); emit_move_insn (src, operands[1]); } @@ -1128,8 +1136,8 @@ else { emit_move_insn (push, operands[2]); - emit_insn (gen_addhi3 (gen_rtx (REG, HImode, HARD_SP_REGNUM), - gen_rtx (REG, HImode, HARD_SP_REGNUM), + emit_insn (gen_addhi3 (gen_rtx_REG (HImode, HARD_SP_REGNUM), + gen_rtx_REG (HImode, HARD_SP_REGNUM), const1_rtx)); } } @@ -1137,15 +1145,15 @@ { /* Source is in X or Y. It's better to push the 16-bit register and then to some stack adjustment. */ - src = gen_rtx (REG, HImode, REGNO (src)); + src = gen_rtx_REG (HImode, REGNO (src)); emit_move_insn (push, src); emit_move_insn (operands[2], const0_rtx); - emit_insn (gen_addhi3 (gen_rtx (REG, HImode, HARD_SP_REGNUM), - gen_rtx (REG, HImode, HARD_SP_REGNUM), + emit_insn (gen_addhi3 (gen_rtx_REG (HImode, HARD_SP_REGNUM), + gen_rtx_REG (HImode, HARD_SP_REGNUM), const1_rtx)); emit_move_insn (push, operands[2]); - emit_insn (gen_addhi3 (gen_rtx (REG, HImode, HARD_SP_REGNUM), - gen_rtx (REG, HImode, HARD_SP_REGNUM), + emit_insn (gen_addhi3 (gen_rtx_REG (HImode, HARD_SP_REGNUM), + gen_rtx_REG (HImode, HARD_SP_REGNUM), const1_rtx)); } emit_move_insn (push, operands[2]); @@ -1169,13 +1177,13 @@ /* Source operand must be in a hard register. */ if (!H_REG_P (src)) { - src = gen_rtx (REG, QImode, REGNO (operands[2])); + src = gen_rtx_REG (QImode, REGNO (operands[2])); emit_move_insn (src, operands[1]); } emit_move_insn (m68hc11_gen_lowpart (QImode, low2), src); emit_move_insn (operands[2], const0_rtx); - src = gen_rtx (REG, QImode, REGNO (operands[2])); + src = gen_rtx_REG (QImode, REGNO (operands[2])); emit_move_insn (m68hc11_gen_highpart (QImode, low2), src); emit_move_insn (m68hc11_gen_highpart (HImode, low), operands[2]); @@ -1314,35 +1322,35 @@ " if (X_REG_P (operands[1])) { - emit_insn (gen_swap_areg (gen_rtx (REG, HImode, HARD_D_REGNUM), - gen_rtx (REG, HImode, HARD_X_REGNUM))); - emit_insn (gen_zero_extendqihi2 (gen_rtx (REG, HImode, HARD_D_REGNUM), - gen_rtx (REG, QImode, HARD_D_REGNUM))); - emit_move_insn (gen_rtx (REG, HImode, HARD_X_REGNUM), + emit_insn (gen_swap_areg (gen_rtx_REG (HImode, HARD_D_REGNUM), + gen_rtx_REG (HImode, HARD_X_REGNUM))); + emit_insn (gen_zero_extendqihi2 (gen_rtx_REG (HImode, HARD_D_REGNUM), + gen_rtx_REG (QImode, HARD_D_REGNUM))); + emit_move_insn (gen_rtx_REG (HImode, HARD_X_REGNUM), const0_rtx); DONE; } - if (reg_mentioned_p (gen_rtx (REG, HImode, HARD_X_REGNUM), operands[1])) + if (reg_mentioned_p (gen_rtx_REG (HImode, HARD_X_REGNUM), operands[1])) { emit_insn (gen_zero_extendqihi2 (m68hc11_gen_lowpart (HImode, operands[0]), operands[1])); - emit_move_insn (gen_rtx (REG, HImode, HARD_X_REGNUM), const0_rtx); + emit_move_insn (gen_rtx_REG (HImode, HARD_X_REGNUM), const0_rtx); DONE; } operands[4] = m68hc11_gen_highpart (HImode, operands[0]); operands[5] = m68hc11_gen_lowpart (HImode, operands[0]); if (A_REG_P (operands[1])) { - operands[2] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM); - operands[3] = gen_rtx (REG, HImode, REGNO (operands[1])); - operands[6] = gen_rtx (REG, QImode, SOFT_TMP_REGNUM); + operands[2] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM); + operands[3] = gen_rtx_REG (HImode, REGNO (operands[1])); + operands[6] = gen_rtx_REG (QImode, SOFT_TMP_REGNUM); } else { operands[5] = operands[2] = - operands[3] = gen_rtx (REG, HImode, HARD_D_REGNUM); + operands[3] = gen_rtx_REG (HImode, HARD_D_REGNUM); operands[6] = operands[1]; } ") @@ -1428,7 +1436,7 @@ { if (!D_REG_P (operands[1])) { - ops[0] = gen_rtx (REG, QImode, HARD_D_REGNUM); + ops[0] = gen_rtx_REG (QImode, HARD_D_REGNUM); ops[1] = operands[1]; m68hc11_gen_movqi (insn, ops); } @@ -1483,7 +1491,7 @@ if (X_REG_P (operands[0])) output_asm_insn (\"dex\", operands); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[2])); + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[2])); if (!X_REG_P (operands[0])) { @@ -1534,7 +1542,7 @@ { if (!D_REG_P (operands[1])) { - ops[0] = gen_rtx (REG, QImode, HARD_D_REGNUM); + ops[0] = gen_rtx_REG (QImode, HARD_D_REGNUM); ops[1] = operands[1]; m68hc11_gen_movqi (insn, ops); } @@ -1552,7 +1560,7 @@ output_asm_insn (\"bpl\\t%l0\", ops); output_asm_insn (\"deca\", operands); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); } else @@ -1570,7 +1578,7 @@ output_asm_insn (\"bpl\\t%l0\", ops); } output_asm_insn (\"dec\\t%h0\", operands); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); } @@ -1615,7 +1623,7 @@ x_reg_used = reg_mentioned_p (ix_reg, operands[1]); if (x_reg_used) { - ops[0] = gen_rtx (REG, HImode, HARD_D_REGNUM); + ops[0] = gen_rtx_REG (HImode, HARD_D_REGNUM); ops[1] = operands[1]; m68hc11_gen_movhi (insn, ops); } @@ -1628,7 +1636,7 @@ Don't use it; keep it for documentation. */ if (!D_REG_P (operands[1]) && !x_reg_used) { - ops[0] = gen_rtx (REG, HImode, HARD_D_REGNUM); + ops[0] = gen_rtx_REG (HImode, HARD_D_REGNUM); ops[1] = operands[1]; m68hc11_gen_movhi (insn, ops); } @@ -1645,7 +1653,7 @@ } else { - ops[0] = gen_rtx (REG, HImode, HARD_D_REGNUM); + ops[0] = gen_rtx_REG (HImode, HARD_D_REGNUM); ops[1] = operands[1]; m68hc11_gen_movhi (insn, ops); } @@ -1653,7 +1661,7 @@ ops[0] = gen_label_rtx (); output_asm_insn (\"bpl\\t%l0\", ops); output_asm_insn (\"dex\", operands); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); return \"\"; }") @@ -1666,7 +1674,7 @@ [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m") (umin:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") (match_operand:QI 2 "general_operand" "m,d")))] - "TARGET_M6812" + "TARGET_M6812 && TARGET_MIN_MAX" "* { /* Flags are set according to (sub:QI (operand 1) (operand2)). @@ -1688,7 +1696,7 @@ [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m") (umax:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") (match_operand:QI 2 "general_operand" "m,d")))] - "TARGET_M6812" + "TARGET_M6812 && TARGET_MIN_MAX" "* { /* Flags are set according to (sub:QI (operand 1) (operand2)). @@ -1710,7 +1718,7 @@ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m") (umin:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") (match_operand:HI 2 "general_operand" "m,d")))] - "TARGET_M6812" + "TARGET_M6812 && TARGET_MIN_MAX" "* { /* Flags are set according to (sub:HI (operand 1) (operand2)). */ @@ -1729,7 +1737,7 @@ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m") (umax:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") (match_operand:HI 2 "general_operand" "m,d")))] - "TARGET_M6812" + "TARGET_M6812 && TARGET_MIN_MAX" "* { /* Flags are set according to (sub:HI (operand 1) (operand2)). */ @@ -1792,7 +1800,7 @@ } else if (!D_REG_P (operands[1])) { - ops[0] = gen_rtx (REG, HImode, HARD_D_REGNUM); + ops[0] = gen_rtx_REG (HImode, HARD_D_REGNUM); ops[1] = operands[1]; m68hc11_gen_movhi (insn, ops); } @@ -1810,7 +1818,7 @@ output_asm_insn (\"inx\", ops); CC_STATUS_INIT; - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[2])); + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[2])); return \"\"; }") @@ -1846,8 +1854,8 @@ { if (H_REG_P (operands[1])) { - ops[0] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM); - ops[1] = gen_rtx (REG, HImode, REGNO (operands[1])); + ops[0] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM); + ops[1] = gen_rtx_REG (HImode, REGNO (operands[1])); m68hc11_gen_movhi (insn, ops); } else @@ -1864,7 +1872,7 @@ } else if (!D_REG_P (operands[1])) { - ops[0] = gen_rtx (REG, QImode, HARD_D_REGNUM); + ops[0] = gen_rtx_REG (QImode, HARD_D_REGNUM); ops[1] = operands[1]; m68hc11_gen_movqi (insn, ops); } @@ -1892,7 +1900,7 @@ output_asm_insn (\"bcc\\t%l3\", ops); output_asm_insn (\"inx\", ops); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[3])); } CC_STATUS_INIT; @@ -1995,7 +2003,7 @@ output_asm_insn (inch_mem, ops); } } - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[2])); + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[2])); CC_STATUS_INIT; return \"\"; @@ -2014,7 +2022,7 @@ "operands[4] = m68hc11_gen_highpart (HImode, operands[2]); if (X_REG_P (operands[0])) { - operands[5] = operands[6] = gen_rtx (REG, HImode, HARD_D_REGNUM); + operands[5] = operands[6] = gen_rtx_REG (HImode, HARD_D_REGNUM); } else { @@ -2060,7 +2068,7 @@ ops[0] = gen_label_rtx (); output_asm_insn (\"bcc\\t%l0\", ops); output_asm_insn (\"in%0\", operands); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); CC_STATUS_INIT; return \"\"; }") @@ -2077,21 +2085,21 @@ { if (TARGET_M6811 && SP_REG_P (operands[0])) { - emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, + emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, + gen_rtx_SET (VOIDmode, operand0, - gen_rtx (PLUS, HImode, + gen_rtx_PLUS (HImode, operand1, operand2)), - gen_rtx (CLOBBER, VOIDmode, - gen_rtx (SCRATCH, HImode))))); + gen_rtx_CLOBBER (VOIDmode, + gen_rtx_SCRATCH (HImode))))); DONE; } }") (define_insn "*addhi3_68hc12" - [(set (match_operand:HI 0 "register_operand" "=xy,d,xy*z*w,xy*z*w,xy*z") - (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,xy*zw,0") - (match_operand:HI 2 "general_operand" "N,im*A*wu,id,id,!mu*A")))] + [(set (match_operand:HI 0 "register_operand" "=d*A,d,xy*A*w,xy*A*w,xy*A") + (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,xy*Aw,0") + (match_operand:HI 2 "general_operand" "i,m*A*wu,id,id,!mu*A")))] "TARGET_M6812" "* { @@ -2213,8 +2221,8 @@ HOST_WIDE_INT val; if (optimize && Y_REG_P (operands[3]) - && dead_register_here (insn, gen_rtx (REG, HImode, HARD_X_REGNUM))) - operands[3] = gen_rtx (REG, HImode, HARD_X_REGNUM); + && dead_register_here (insn, gen_rtx_REG (HImode, HARD_X_REGNUM))) + operands[3] = gen_rtx_REG (HImode, HARD_X_REGNUM); if (GET_CODE (operands[2]) == CONST_INT && (val = INTVAL (operands[2])) != 0 @@ -2258,8 +2266,8 @@ Register X/Y is lost, this is specified by the (clobber) statement. */ output_asm_insn (\"ts%3\", operands); if (GET_CODE (operands[2]) == CONST_INT - && ((val = INTVAL (operands[2]) >= 0 && val < 0x100)) - && dead_register_here (insn, gen_rtx (REG, HImode, HARD_D_REGNUM))) + && ((val = INTVAL (operands[2])) >= 0 && val < 0x100) + && dead_register_here (insn, gen_rtx_REG (HImode, HARD_D_REGNUM))) { output_asm_insn (\"ldab\\t%2\", operands); output_asm_insn (\"ab%3\", operands); @@ -2278,9 +2286,9 @@ }") (define_insn "*addhi3" - [(set (match_operand:HI 0 "hard_reg_operand" "=A,d,!A,d*A,!d*A") - (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0,0") - (match_operand:HI 2 "general_operand" "N,i,I,mi*A*d,!u*d*w")))] + [(set (match_operand:HI 0 "hard_reg_operand" "=A,dA,d,!A,d*A,d,!d*A") + (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0,0,0,0") + (match_operand:HI 2 "general_operand" "N,I,i,I,mi*A*d,*u,!u*d*w")))] "TARGET_M6811" "* { @@ -2373,7 +2381,7 @@ [(set (match_operand:HI 0 "hard_reg_operand" "=A,d") (plus:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,um*A")) - (match_operand:HI 2 "hard_reg_operand" "0,0")))] + (match_operand:HI 2 "general_operand" "0,0")))] "" "* { @@ -2519,26 +2527,26 @@ if (A_REG_P (operands[2])) { if (TARGET_M6812) - ops[0] = gen_rtx (MEM, HImode, - gen_rtx (PRE_DEC, HImode, - gen_rtx (REG, HImode, HARD_SP_REGNUM))); + ops[0] = gen_rtx_MEM (HImode, + gen_rtx_PRE_DEC (HImode, + gen_rtx_REG (HImode, HARD_SP_REGNUM))); else - ops[0] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM); + ops[0] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM); ops[1] = operands[2]; m68hc11_gen_movhi (insn, ops); if (TARGET_M6812) - operands[2] = gen_rtx (MEM, HImode, - gen_rtx (POST_INC, HImode, - gen_rtx (REG, HImode, HARD_SP_REGNUM))); + operands[2] = gen_rtx_MEM (HImode, + gen_rtx_POST_INC (HImode, + gen_rtx_REG (HImode, HARD_SP_REGNUM))); else - operands[2] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM); + operands[2] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM); } ops[0] = gen_label_rtx (); output_asm_insn (\"subd\\t%2\", operands); output_asm_insn (\"bcc\\t%l0\", ops); output_asm_insn (\"dex\", ops); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); CC_STATUS_INIT; return \"\"; }") @@ -2555,17 +2563,17 @@ if (A_REG_P (operands[2])) { - ops[0] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM); + ops[0] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM); ops[1] = operands[2]; m68hc11_gen_movhi (insn, ops); - operands[2] = gen_rtx (REG, QImode, SOFT_TMP_REGNUM); + operands[2] = gen_rtx_REG (QImode, SOFT_TMP_REGNUM); } ops[0] = gen_label_rtx (); output_asm_insn (\"subb\\t%b2\", operands); output_asm_insn (\"sbca\\t#0\", operands); output_asm_insn (\"bcc\\t%l0\", ops); output_asm_insn (\"dex\", ops); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); CC_STATUS_INIT; return \"\"; }") @@ -2706,9 +2714,9 @@ (define_insn "*subhi3" - [(set (match_operand:HI 0 "register_operand" "=d,*A,d*A") - (minus:HI (match_operand:HI 1 "register_operand" "0,0,0") - (match_operand:HI 2 "general_operand" "im*A*d,im*d*A,!u")))] + [(set (match_operand:HI 0 "register_operand" "=d,*A,d,*A") + (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0") + (match_operand:HI 2 "general_operand" "im*A*d,im*d*A,u,!u")))] "" "* { @@ -2722,7 +2730,7 @@ (define_insn "*subhi3_zext" [(set (match_operand:HI 0 "hard_reg_operand" "=d,d") - (minus:HI (match_operand:HI 1 "hard_reg_operand" "0,0") + (minus:HI (match_operand:HI 1 "general_operand" "0,0") (zero_extend:HI (match_operand:QI 2 "general_operand" "mi*A,!u"))))] "" "* @@ -2732,7 +2740,7 @@ { rtx ops[2]; - ops[0] = gen_rtx (REG, QImode, SOFT_TMP_REGNUM); + ops[0] = gen_rtx_REG (QImode, SOFT_TMP_REGNUM); ops[1] = operands[2]; m68hc11_gen_movqi (insn, ops); return \"subb\\t%T0\\n\\tsbca\\t#0\"; @@ -2742,7 +2750,7 @@ (define_insn "subqi3" [(set (match_operand:QI 0 "hard_reg_operand" "=dq,!*x*y") - (minus:QI (match_operand:QI 1 "hard_reg_operand" "0,0") + (minus:QI (match_operand:QI 1 "general_operand" "0,0") (match_operand:QI 2 "general_operand" "uim*A*d,uim*A*d")))] "" "* @@ -2879,7 +2887,7 @@ operands[1] = temp; } - ops[0] = gen_rtx (REG, QImode, HARD_A_REGNUM); + ops[0] = gen_rtx_REG (QImode, HARD_A_REGNUM); ops[1] = operands[2]; m68hc11_gen_movqi (insn, ops); @@ -2894,12 +2902,15 @@ }") (define_insn "mulqi3" - [(set (match_operand:QI 0 "register_operand" "=d") - (mult:QI (match_operand:QI 1 "nonimmediate_operand" "dum") - (match_operand:QI 2 "nonimmediate_operand" "dum")))] + [(set (match_operand:QI 0 "register_operand" "=d,*x,*y") + (mult:QI (match_operand:QI 1 "general_operand" "%di*um,0,0") + (match_operand:QI 2 "general_operand" "di*um,*xium,*yium")))] "" "* { + if (A_REG_P (operands[0])) + return \"#\"; + if (D_REG_P (operands[1]) && D_REG_P (operands[2])) { output_asm_insn (\"tba\", operands); @@ -2925,12 +2936,34 @@ return \"mul\"; }") +(define_split + [(set (match_operand:QI 0 "hard_addr_reg_operand" "") + (mult:QI (match_operand:QI 1 "general_operand" "") + (match_operand:QI 2 "general_operand" "")))] + "z_replacement_completed == 2" + [(parallel [(set (reg:HI D_REGNUM) (match_dup 3)) + (set (match_dup 3) (reg:HI D_REGNUM))]) + (set (reg:QI D_REGNUM) (mult:QI (match_dup 5) (match_dup 6))) + (parallel [(set (reg:HI D_REGNUM) (match_dup 3)) + (set (match_dup 3) (reg:HI D_REGNUM))])] + " + operands[3] = gen_rtx_REG (HImode, REGNO (operands[0])); + if (A_REG_P (operands[1])) + operands[5] = gen_rtx_REG (QImode, HARD_D_REGNUM); + else + operands[5] = operands[1]; + if (A_REG_P (operands[2])) + operands[6] = gen_rtx_REG (QImode, HARD_D_REGNUM); + else + operands[6] = operands[2]; + ") + (define_insn "mulqihi3" - [(set (match_operand:HI 0 "register_operand" "=d,d") + [(set (match_operand:HI 0 "register_operand" "=d,d,d") (mult:HI (sign_extend:HI - (match_operand:QI 1 "register_operand" "%0,0")) + (match_operand:QI 1 "register_operand" "%0,0,0")) (sign_extend:HI - (match_operand:QI 2 "nonimmediate_operand" "dm,*A"))))] + (match_operand:QI 2 "general_operand" "mi*u,*A,0"))))] "" "* { @@ -2951,7 +2984,7 @@ { rtx ops[2]; - ops[0] = gen_rtx (REG, QImode, HARD_A_REGNUM); + ops[0] = gen_rtx_REG (QImode, HARD_A_REGNUM); ops[1] = operands[2]; m68hc11_gen_movqi (insn, ops); } @@ -3028,21 +3061,29 @@ ;;- and instructions. ;;-------------------------------------------------------------------- -(define_insn "anddi3" +(define_insn_and_split "anddi3" [(set (match_operand:DI 0 "reg_or_some_mem_operand" "=m,u") (and:DI (match_operand:DI 1 "reg_or_some_mem_operand" "%imu,imu") (match_operand:DI 2 "general_operand" "imu,imu"))) (clobber (match_scratch:HI 3 "=d,d"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_logical (SImode, AND, operands); + DONE;") -(define_insn "andsi3" +(define_insn_and_split "andsi3" [(set (match_operand:SI 0 "register_operand" "=D,!u") (and:SI (match_operand:SI 1 "register_operand" "%0,0") (match_operand:SI 2 "general_operand" "Dimu,imu"))) (clobber (match_scratch:HI 3 "=X,d"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_logical (HImode, AND, operands); + DONE;") (define_expand "andhi3" [(set (match_operand:HI 0 "register_operand" "") @@ -3052,10 +3093,10 @@ "") (define_insn "*andhi3_mem" - [(set (match_operand:HI 0 "memory_operand" "=Q,R") + [(set (match_operand:HI 0 "memory_operand" "=R,Q") (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "i,i"))) - (clobber (match_scratch:HI 2 "=xy,X"))] + (clobber (match_scratch:HI 2 "=X,xy"))] "TARGET_RELAX && !TARGET_M6812" "* { @@ -3075,7 +3116,7 @@ /* When destination is a global variable, generate a .relax instruction and load the address in the clobber register. That load can be eliminated by the linker if the address is in page0. */ - if (which_alternative == 0) + if (which_alternative == 1) { rtx ops[3]; @@ -3090,7 +3131,7 @@ if ((val & 0x0FF00) != 0x0FF00) output_asm_insn (\"bclr\\t0,%2, %h1\", operands); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[2])); return \"\"; } @@ -3190,8 +3231,8 @@ (define_insn "*andhi3_gen" [(set (match_operand:HI 0 "register_operand" "=d,d,!*A") - (and:HI (match_operand:HI 1 "register_operand" "%0,0,0") - (match_operand:HI 2 "general_operand" "mi,!u*A,!um*A")))] + (and:HI (match_operand:HI 1 "splitable_operand" "%0,0,0") + (match_operand:HI 2 "splitable_operand" "mi,!u*A,!um*Ai")))] "" "* { @@ -3210,10 +3251,10 @@ "") (define_insn "*andqi3_mem" - [(set (match_operand:QI 0 "memory_operand" "=Q,R") + [(set (match_operand:QI 0 "memory_operand" "=R,Q") (and:QI (match_dup 0) (match_operand:QI 1 "const_int_operand" "i,i"))) - (clobber (match_scratch:HI 2 "=xy,X"))] + (clobber (match_scratch:HI 2 "=X,xy"))] "TARGET_RELAX && !TARGET_M6812" "* { @@ -3231,7 +3272,7 @@ /* When destination is a global variable, generate a .relax instruction and load the address in the clobber register. That load can be eliminated by the linker if the address is in page0. */ - if (which_alternative == 0) + if (which_alternative == 1) { rtx ops[3]; @@ -3241,7 +3282,7 @@ output_asm_insn (\".relax\\t%l2\", ops); m68hc11_gen_movhi (insn, ops); output_asm_insn (\"bclr\\t0,%2, %1\", operands); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[2])); return \"\"; } @@ -3284,8 +3325,8 @@ (define_insn "*andqi3_gen" [(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q") - (and:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0") - (match_operand:QI 2 "general_operand" "mi,!u,?*A,!um,?*A*d,!um*A")))] + (and:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0") + (match_operand:QI 2 "general_operand" "mi,!*u,?*A,!*um,?*A*d,!*um*A")))] "" "* { @@ -3304,34 +3345,42 @@ ;;- Bit set or instructions. ;;-------------------------------------------------------------------- -(define_insn "iordi3" +(define_insn_and_split "iordi3" [(set (match_operand:DI 0 "reg_or_some_mem_operand" "=m,u") (ior:DI (match_operand:DI 1 "reg_or_some_mem_operand" "%imu,imu") (match_operand:DI 2 "general_operand" "imu,imu"))) (clobber (match_scratch:HI 3 "=d,d"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_logical (SImode, IOR, operands); + DONE;") -(define_insn "iorsi3" +(define_insn_and_split "iorsi3" [(set (match_operand:SI 0 "register_operand" "=D,!u") (ior:SI (match_operand:SI 1 "register_operand" "%0,0") (match_operand:SI 2 "general_operand" "Dimu,imu"))) (clobber (match_scratch:HI 3 "=X,d"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_logical (HImode, IOR, operands); + DONE;") (define_expand "iorhi3" [(set (match_operand:HI 0 "register_operand" "") (ior:HI (match_operand:HI 1 "register_operand" "") - (match_operand:HI 2 "general_operand" "")))] + (match_operand:HI 2 "splitable_operand" "")))] "" "") (define_insn "*iorhi3_mem" - [(set (match_operand:HI 0 "memory_operand" "=Q,R") + [(set (match_operand:HI 0 "memory_operand" "=R,Q") (ior:HI (match_dup 0) (match_operand:HI 1 "const_int_operand" ""))) - (clobber (match_scratch:HI 2 "=xy,X"))] + (clobber (match_scratch:HI 2 "=X,xy"))] "TARGET_RELAX && !TARGET_M6812" "* { @@ -3343,7 +3392,7 @@ return \"\"; } CC_STATUS_INIT; - if (which_alternative == 0) + if (which_alternative == 1) { rtx ops[3]; @@ -3357,7 +3406,7 @@ if ((val & 0x0FF00) != 0) output_asm_insn (\"bset\\t0,%2, %h1\", operands); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[2])); return \"\"; } @@ -3411,8 +3460,8 @@ (define_insn "*iorhi3_gen" [(set (match_operand:HI 0 "register_operand" "=d,d,!*A") - (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0") - (match_operand:HI 2 "general_operand" "mi,!u*A,!um*A")))] + (ior:HI (match_operand:HI 1 "splitable_operand" "%0,0,0") + (match_operand:HI 2 "splitable_operand" "mi,!u*A,!um*Ai")))] "" "* { @@ -3431,10 +3480,10 @@ "") (define_insn "*iorqi3_mem" - [(set (match_operand:QI 0 "memory_operand" "=Q,R") + [(set (match_operand:QI 0 "memory_operand" "=R,Q") (ior:QI (match_dup 0) (match_operand:QI 1 "const_int_operand" ""))) - (clobber (match_scratch:HI 2 "=xy,X"))] + (clobber (match_scratch:HI 2 "=X,xy"))] "TARGET_RELAX && !TARGET_M6812" "* { @@ -3445,7 +3494,7 @@ cc_status = cc_prev_status; return \"\"; } - if (which_alternative == 0) + if (which_alternative == 1) { rtx ops[3]; @@ -3455,7 +3504,7 @@ output_asm_insn (\".relax\\t%l2\", ops); m68hc11_gen_movhi (insn, ops); output_asm_insn (\"bset\\t0,%2, %1\", operands); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[2])); return \"\"; } @@ -3494,8 +3543,8 @@ (define_insn "*iorqi3_gen" [(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q") - (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0") - (match_operand:QI 2 "general_operand" "mi,!u,!*A,!um,?*A*d,!um*A")))] + (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0") + (match_operand:QI 2 "general_operand" "mi,!*u,!*A,!*um,?*A*d,!*um*A")))] "" "* { @@ -3515,26 +3564,34 @@ ;;- xor instructions. ;;-------------------------------------------------------------------- -(define_insn "xordi3" +(define_insn_and_split "xordi3" [(set (match_operand:DI 0 "reg_or_some_mem_operand" "=m,u") (xor:DI (match_operand:DI 1 "reg_or_some_mem_operand" "%imu,imu") (match_operand:DI 2 "general_operand" "imu,imu"))) (clobber (match_scratch:HI 3 "=d,d"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_logical (SImode, XOR, operands); + DONE;") -(define_insn "xorsi3" +(define_insn_and_split "xorsi3" [(set (match_operand:SI 0 "register_operand" "=D,!u") (xor:SI (match_operand:SI 1 "register_operand" "%0,0") (match_operand:SI 2 "general_operand" "Dimu,imu"))) (clobber (match_scratch:HI 3 "=X,d"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_logical (HImode, XOR, operands); + DONE;") (define_insn "xorhi3" [(set (match_operand:HI 0 "register_operand" "=d,d,!*A") - (xor:HI (match_operand:HI 1 "register_operand" "%0,0,0") - (match_operand:HI 2 "general_operand" "im,!u*A,!ium*A")))] + (xor:HI (match_operand:HI 1 "splitable_operand" "%0,0,0") + (match_operand:HI 2 "splitable_operand" "im,!u*A,!ium*A")))] "" "* { @@ -3578,8 +3635,8 @@ (define_insn "xorqi3" [(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q") - (xor:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0") - (match_operand:QI 2 "general_operand" "im,!u,!*A,!ium,?*A*d,!ium*A")))] + (xor:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0") + (match_operand:QI 2 "general_operand" "im,!*u,!*A,!i*um,?*A*d,!i*um*A")))] "" "* { @@ -3615,30 +3672,47 @@ ;;- Bit set or instructions. ;;-------------------------------------------------------------------- -(define_insn "*logicalsi3_zexthi" +(define_insn_and_split "*logicalsi3_zexthi" [(set (match_operand:SI 0 "register_operand" "=D") (match_operator:SI 3 "m68hc11_logical_operator" [(zero_extend:SI (match_operand:HI 1 "general_operand" "imudA")) (match_operand:SI 2 "general_operand" "Dimu")]))] "" - "#") + "#" + "reload_completed" + [(set (reg:HI D_REGNUM) (match_dup 4)) + (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)])) + (set (reg:HI X_REGNUM) (match_dup 6))] + "PUT_MODE (operands[3], HImode); + if (X_REG_P (operands[2])) + { + operands[5] = operands[1]; + /* Make all the (set (REG:x) (REG:y)) a nop set. */ + operands[4] = gen_rtx_REG (HImode, HARD_D_REGNUM); + operands[6] = gen_rtx_REG (HImode, HARD_X_REGNUM); + } + else + { + operands[4] = operands[1]; + operands[5] = m68hc11_gen_lowpart (HImode, operands[2]); + operands[6] = m68hc11_gen_highpart (HImode, operands[2]); + } + /* For an AND, make sure the high 16-bit part is cleared. */ + if (GET_CODE (operands[3]) == AND) + { + operands[6] = const0_rtx; + } + ") -(define_insn "*logicalsi3_zextqi" +(define_insn_and_split "*logicalsi3_zextqi" [(set (match_operand:SI 0 "register_operand" "=D,D,D") (match_operator:SI 3 "m68hc11_logical_operator" [(zero_extend:SI (match_operand:QI 1 "general_operand" "d,*A,imu")) (match_operand:SI 2 "general_operand" "imu,imu,0")]))] "" - "#") - -(define_split /* logicalsi3_zextqi */ - [(set (match_operand:SI 0 "register_operand" "") - (match_operator:SI 3 "m68hc11_logical_operator" - [(zero_extend:SI - (match_operand:QI 1 "general_operand" "")) - (match_operand:SI 2 "general_operand" "")]))] + "#" "z_replacement_completed == 2" [(set (reg:QI A_REGNUM) (match_dup 4)) (set (reg:QI D_REGNUM) (match_dup 7)) @@ -3649,9 +3723,9 @@ { operands[5] = operands[1]; /* Make all the (set (REG:x) (REG:y)) a nop set. */ - operands[4] = gen_rtx (REG, QImode, HARD_A_REGNUM); - operands[7] = gen_rtx (REG, QImode, HARD_D_REGNUM); - operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM); + operands[4] = gen_rtx_REG (QImode, HARD_A_REGNUM); + operands[7] = gen_rtx_REG (QImode, HARD_D_REGNUM); + operands[6] = gen_rtx_REG (HImode, HARD_X_REGNUM); } else { @@ -3669,63 +3743,47 @@ } ") -(define_split /* logicalsi3_zexthi */ - [(set (match_operand:SI 0 "register_operand" "") - (match_operator:SI 3 "m68hc11_logical_operator" - [(zero_extend:SI - (match_operand:HI 1 "general_operand" "")) - (match_operand:SI 2 "general_operand" "")]))] - "reload_completed" - [(set (reg:HI D_REGNUM) (match_dup 4)) - (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)])) - (set (reg:HI X_REGNUM) (match_dup 6))] - "PUT_MODE (operands[3], HImode); - if (X_REG_P (operands[2])) - { - operands[5] = operands[1]; - /* Make all the (set (REG:x) (REG:y)) a nop set. */ - operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM); - operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM); - } - else - { - operands[4] = operands[1]; - operands[5] = m68hc11_gen_lowpart (HImode, operands[2]); - operands[6] = m68hc11_gen_highpart (HImode, operands[2]); - } - /* For an AND, make sure the high 16-bit part is cleared. */ - if (GET_CODE (operands[3]) == AND) - { - operands[6] = const0_rtx; - } - ") - -(define_insn "*logicalhi3_zexthi_ashift8" +(define_insn_and_split "*logicalhi3_zexthi_ashift8" [(set (match_operand:HI 0 "register_operand" "=d") (match_operator:HI 3 "m68hc11_logical_operator" [(zero_extend:HI - (match_operand:QI 1 "general_operand" "imud")) + (match_operand:QI 1 "general_operand" "imud*A")) (ashift:HI - (match_operand:HI 2 "general_operand" "dimu") + (match_operand:HI 2 "general_operand" "imud*A") (const_int 8))]))] "" - "#") + "#" + "z_replacement_completed == 2" + [(set (reg:QI A_REGNUM) (match_dup 4)) + (set (reg:QI B_REGNUM) (match_dup 5))] + " + if (GET_CODE (operands[3]) == AND) + { + emit_insn (gen_movhi (operands[0], const0_rtx)); + DONE; + } + else + { + operands[5] = operands[1]; + if (D_REG_P (operands[2])) + { + operands[4] = gen_rtx_REG (QImode, HARD_B_REGNUM); + } + else + { + operands[4] = m68hc11_gen_lowpart (QImode, operands[2]); + } + } + ") -(define_insn "*logicalhi3_zexthi" +(define_insn_and_split "*logicalhi3_zexthi" [(set (match_operand:HI 0 "register_operand" "=d,d") (match_operator:HI 3 "m68hc11_logical_operator" [(zero_extend:HI (match_operand:QI 1 "general_operand" "imd*A,?u")) (match_operand:HI 2 "general_operand" "dim,?dimu")]))] "" - "#") - -(define_split /* logicalhi3_zexthi */ - [(set (match_operand:HI 0 "register_operand" "") - (match_operator:HI 3 "m68hc11_logical_operator" - [(zero_extend:HI - (match_operand:QI 1 "general_operand" "")) - (match_operand:HI 2 "general_operand" "")]))] + "#" "z_replacement_completed == 2" [(set (reg:QI B_REGNUM) (match_dup 6)) (set (reg:QI A_REGNUM) (match_dup 4)) @@ -3734,16 +3792,16 @@ PUT_MODE (operands[3], QImode); if (D_REG_P (operands[2])) { - operands[4] = gen_rtx (REG, QImode, HARD_A_REGNUM); + operands[4] = gen_rtx_REG (QImode, HARD_A_REGNUM); operands[5] = operands[1]; - operands[6] = gen_rtx (REG, QImode, HARD_B_REGNUM); + operands[6] = gen_rtx_REG (QImode, HARD_B_REGNUM); } else { operands[4] = m68hc11_gen_highpart (QImode, operands[2]); operands[5] = m68hc11_gen_lowpart (QImode, operands[2]); if (D_REG_P (operands[1])) - operands[6] = gen_rtx (REG, QImode, HARD_B_REGNUM); + operands[6] = gen_rtx_REG (QImode, HARD_B_REGNUM); else operands[6] = operands[1]; } @@ -3754,54 +3812,16 @@ } ") -(define_split /* logicalhi3_zexthi_ashift8 */ - [(set (match_operand:HI 0 "register_operand" "") - (match_operator:HI 3 "m68hc11_logical_operator" - [(zero_extend:HI - (match_operand:QI 1 "general_operand" "")) - (ashift:HI - (match_operand:HI 2 "general_operand" "") - (const_int 8))]))] - "z_replacement_completed == 2" - [(set (reg:QI A_REGNUM) (match_dup 4)) - (set (reg:QI B_REGNUM) (match_dup 5))] - " - if (GET_CODE (operands[3]) == AND) - { - emit_insn (gen_movhi (operands[0], const0_rtx)); - DONE; - } - else - { - operands[5] = operands[1]; - if (D_REG_P (operands[2])) - { - operands[4] = gen_rtx (REG, QImode, HARD_B_REGNUM); - } - else - { - operands[4] = m68hc11_gen_lowpart (QImode, operands[2]); - } - } - ") -(define_insn "*logicalsi3_silshr16" - [(set (match_operand:SI 0 "register_operand" "=D,D,D") +(define_insn_and_split "*logicalsi3_silshr16" + [(set (match_operand:SI 0 "register_operand" "=D,D,D,?D") (match_operator:SI 3 "m68hc11_logical_operator" [(lshiftrt:SI - (match_operand:SI 1 "general_operand" "uim,uim,?D") + (match_operand:SI 1 "general_operand" "uim,uim,0,0") (const_int 16)) - (match_operand:SI 2 "general_operand" "uim,0,0")]))] + (match_operand:SI 2 "general_operand" "uim,0,uim,0")]))] "" - "#") - -(define_split /* logicalsi3_silshr16 */ - [(set (match_operand:SI 0 "register_operand" "") - (match_operator:SI 3 "m68hc11_logical_operator" - [(lshiftrt:SI - (match_operand:SI 1 "general_operand" "") - (const_int 16)) - (match_operand:SI 2 "general_operand" "")]))] + "#" "reload_completed" [(set (reg:HI D_REGNUM) (match_dup 4)) (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)])) @@ -3809,8 +3829,8 @@ "operands[5] = m68hc11_gen_highpart (HImode, operands[1]); if (X_REG_P (operands[2])) { - operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM); - operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM); + operands[4] = gen_rtx_REG (HImode, HARD_D_REGNUM); + operands[6] = gen_rtx_REG (HImode, HARD_X_REGNUM); } else { @@ -3826,7 +3846,7 @@ } ") -(define_insn "*logicalsi3_silshl16" +(define_insn_and_split "*logicalsi3_silshl16" [(set (match_operand:SI 0 "register_operand" "=D,D") (match_operator:SI 3 "m68hc11_logical_operator" [(ashift:SI @@ -3834,15 +3854,7 @@ (const_int 16)) (match_operand:SI 2 "general_operand" "0,0")]))] "" - "#") - -(define_split /* logicalsi3_silshl16 */ - [(set (match_operand:SI 0 "register_operand" "") - (match_operator:SI 3 "m68hc11_logical_operator" - [(ashift:SI - (match_operand:SI 1 "general_operand" "") - (const_int 16)) - (match_operand:SI 2 "general_operand" "")]))] + "#" "z_replacement_completed == 2" [(set (reg:HI X_REGNUM) (match_op_dup 3 [(reg:HI X_REGNUM) (match_dup 4)])) (set (reg:HI D_REGNUM) (match_dup 5))] @@ -3852,51 +3864,48 @@ if (GET_CODE (operands[3]) == AND) operands[5] = const0_rtx; else - operands[5] = gen_rtx (REG, HImode, HARD_D_REGNUM); + operands[5] = gen_rtx_REG (HImode, HARD_D_REGNUM); ") - -;;-------------------------------------------------------------------- -;;- 64/32-bit Logical Operations. Patterns are defined so that GCC -;; can optimize correctly. These insns are split by the `final' -;; pass (# pattern). They are split to fall in the corresponding -;; 16-bit logical patterns. -;;-------------------------------------------------------------------- - -;; Split 64-bit logical operations: anddi3, iordi3, xordi3 -(define_split - [(set (match_operand:DI 0 "reg_or_some_mem_operand" "") - (match_operator:DI 4 "m68hc11_logical_operator" - [(match_operand:DI 1 "reg_or_some_mem_operand" "") - (match_operand:DI 2 "general_operand" "")])) - (clobber (match_scratch:HI 3 ""))] +(define_insn_and_split "*logicalsi3_silshl16_zext" + [(set (match_operand:SI 0 "register_operand" "=D,D,D") + (match_operator:SI 3 "m68hc11_logical_operator" + [(ashift:SI + (zero_extend:SI + (match_operand:HI 1 "general_operand" "uim,udA,!dA")) + (const_int 16)) + (zero_extend:SI (match_operand:HI 2 "general_operand" "uidA,um,!dA"))]))] + "" + "#" + ;; Must split before z register replacement "reload_completed" - [(const_int 0)] - "m68hc11_split_logical (SImode, GET_CODE (operands[4]), operands); - DONE;") - -;; Split 32-bit logical operations: andsi3, iorsi3, xorsi3 -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (match_operator:SI 3 "m68hc11_logical_operator" - [(match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "general_operand" "")]))] - "0 && reload_completed" - [(const_int 0)] - "m68hc11_split_logical (HImode, GET_CODE (operands[3]), operands); - DONE;") + [(set (match_dup 4) (match_dup 5)) + (set (match_dup 6) (match_dup 7))] + " + /* set (X_REGNUM) (d), set (D_REGNUM) (1) */ + if (GET_CODE (operands[1]) == HARD_D_REGNUM + && GET_CODE (operands[3]) != AND) + { + /* This particular case is too early to be split before + Z register replacement because the cse-reg pass we do + does not recognize the 'swap_areg'. It is ok to handle + this case after. */ + if (z_replacement_completed != 2) + { + FAIL; + } + emit_move_insn (gen_rtx_REG (HImode, HARD_X_REGNUM), operands[2]); + emit_insn (gen_swap_areg (gen_rtx_REG (HImode, HARD_D_REGNUM), + gen_rtx_REG (HImode, HARD_X_REGNUM))); + } + operands[4] = gen_rtx_REG (HImode, HARD_D_REGNUM); + operands[6] = gen_rtx_REG (HImode, HARD_X_REGNUM); + operands[5] = operands[2]; + operands[7] = operands[1]; -;; Split 32-bit logical operations: andsi3, iorsi3, xorsi3 -(define_split - [(set (match_operand:SI 0 "reg_or_some_mem_operand" "") - (match_operator:SI 4 "m68hc11_logical_operator" - [(match_operand:SI 1 "reg_or_some_mem_operand" "") - (match_operand:SI 2 "general_operand" "")])) - (clobber (match_scratch:HI 3 ""))] - "reload_completed" - [(const_int 0)] - "m68hc11_split_logical (HImode, GET_CODE (operands[4]), operands); - DONE;") + if (GET_CODE (operands[3]) == AND) + operands[5] = operands[7] = const0_rtx; + ") ;;-------------------------------------------------------------------- ;; 16-bit Arithmetic and logical operations on X and Y: @@ -3951,12 +3960,12 @@ || (m68hc11_small_indexed_indirect_p (operands[2], HImode) && reg_mentioned_p (operands[0], operands[2])))) { - operands[4] = gen_rtx (MEM, HImode, - gen_rtx (PRE_DEC, HImode, - gen_rtx (REG, HImode, HARD_SP_REGNUM))); - operands[6] = gen_rtx (MEM, HImode, - gen_rtx (POST_INC, HImode, - gen_rtx (REG, HImode, HARD_SP_REGNUM))); + operands[4] = gen_rtx_MEM (HImode, + gen_rtx_PRE_DEC (HImode, + gen_rtx_REG (HImode, HARD_SP_REGNUM))); + operands[6] = gen_rtx_MEM (HImode, + gen_rtx_POST_INC (HImode, + gen_rtx_REG (HImode, HARD_SP_REGNUM))); operands[5] = operands[2]; operands[8] = operands[7] = operands[0]; } @@ -3968,20 +3977,20 @@ if (GET_CODE (operands[3]) == MINUS && reg_mentioned_p (operands[0], operands[2])) { - operands[9] = gen_rtx (MEM, HImode, - gen_rtx (PRE_DEC, HImode, - gen_rtx (REG, HImode, HARD_SP_REGNUM))); - operands[1] = gen_rtx (MEM, HImode, - gen_rtx (POST_INC, HImode, - gen_rtx (REG, HImode, HARD_SP_REGNUM))); - operands[8] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM); + operands[9] = gen_rtx_MEM (HImode, + gen_rtx_PRE_DEC (HImode, + gen_rtx_REG (HImode, HARD_SP_REGNUM))); + operands[1] = gen_rtx_MEM (HImode, + gen_rtx_POST_INC (HImode, + gen_rtx_REG (HImode, HARD_SP_REGNUM))); + operands[8] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM); operands[4] = operands[7] = operands[0]; operands[6] = operands[8]; operands[5] = operands[2]; } else { - operands[4] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM); + operands[4] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM); operands[6] = operands[4]; if (!H_REG_P (operands[2])) { @@ -4049,7 +4058,7 @@ && z_replacement_completed == 2 && !SP_REG_P (operands[2])" [(set (match_dup 4) (match_dup 2)) (set (match_dup 0) (match_op_dup 3 [(match_dup 0) (match_dup 4)]))] - "operands[4] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM);") + "operands[4] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM);") ;; ;; For 68HC12, push the operand[2] value on the stack and do the @@ -4064,12 +4073,12 @@ && z_replacement_completed == 2 && !SP_REG_P (operands[2])" [(set (match_dup 4) (match_dup 2)) (set (match_dup 0) (match_op_dup 3 [(match_dup 0) (match_dup 5)]))] - "operands[4] = gen_rtx (MEM, HImode, - gen_rtx (PRE_DEC, HImode, - gen_rtx (REG, HImode, HARD_SP_REGNUM))); - operands[5] = gen_rtx (MEM, HImode, - gen_rtx (POST_INC, HImode, - gen_rtx (REG, HImode, HARD_SP_REGNUM))); + "operands[4] = gen_rtx_MEM (HImode, + gen_rtx_PRE_DEC (HImode, + gen_rtx_REG (HImode, HARD_SP_REGNUM))); + operands[5] = gen_rtx_MEM (HImode, + gen_rtx_POST_INC (HImode, + gen_rtx_REG (HImode, HARD_SP_REGNUM))); ") ;;-------------------------------------------------------------------- @@ -4108,12 +4117,12 @@ || reg_mentioned_p (operands[0], operands[1])) { /* Move to the destination register, before the xgdx. */ - operands[4] = gen_rtx (REG, GET_MODE (operands[1]), + operands[4] = gen_rtx_REG (GET_MODE (operands[1]), REGNO (operands[0])); operands[5] = operands[1]; /* Apply the operation on D. */ - operands[3] = gen_rtx (REG, GET_MODE (operands[1]), HARD_D_REGNUM); + operands[3] = gen_rtx_REG (GET_MODE (operands[1]), HARD_D_REGNUM); } else { @@ -4149,7 +4158,7 @@ (set (reg:QI D_REGNUM) (match_op_dup 3 [(reg:QI D_REGNUM) (match_dup 7)])) (parallel [(set (reg:HI D_REGNUM) (match_dup 4)) (set (match_dup 4) (reg:HI D_REGNUM))])] - "operands[4] = gen_rtx (REG, HImode, REGNO (operands[0])); + "operands[4] = gen_rtx_REG (HImode, REGNO (operands[0])); /* For the second operand is a hard register or if the address register appears in the source, we have to save the operand[2] @@ -4158,19 +4167,19 @@ will result in a nop. */ if (H_REG_P (operands[2])) { - operands[5] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM); - operands[6] = gen_rtx (REG, HImode, REGNO (operands[2])); - operands[7] = gen_rtx (REG, QImode, SOFT_TMP_REGNUM); + operands[5] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM); + operands[6] = gen_rtx_REG (HImode, REGNO (operands[2])); + operands[7] = gen_rtx_REG (QImode, SOFT_TMP_REGNUM); } else if (reg_mentioned_p (operands[0], operands[2])) { - operands[5] = gen_rtx (REG, QImode, SOFT_TMP_REGNUM); + operands[5] = gen_rtx_REG (QImode, SOFT_TMP_REGNUM); operands[6] = operands[2]; operands[7] = operands[5]; } else { - operands[5] = operands[6] = gen_rtx (REG, QImode, HARD_D_REGNUM); + operands[5] = operands[6] = gen_rtx_REG (QImode, HARD_D_REGNUM); operands[7] = operands[2]; } ") @@ -4195,9 +4204,9 @@ "reload_completed" [(set (match_dup 5) (match_dup 6)) (set (match_dup 0) (match_op_dup 3 [(match_dup 0) (match_dup 4)]))] - "operands[4] = gen_rtx (REG, QImode, SOFT_TMP_REGNUM); - operands[5] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM); - operands[6] = gen_rtx (REG, HImode, REGNO (operands[2]));") + "operands[4] = gen_rtx_REG (QImode, SOFT_TMP_REGNUM); + operands[5] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM); + operands[6] = gen_rtx_REG (HImode, REGNO (operands[2]));") ;;-------------------------------------------------------------------- ;; 8-bit Unary operations on X and Y: @@ -4230,7 +4239,7 @@ (set (match_dup 3) (reg:HI D_REGNUM))])] " { - operands[3] = gen_rtx (REG, HImode, REGNO (operands[0])); + operands[3] = gen_rtx_REG (HImode, REGNO (operands[0])); if ((H_REG_P (operands[1]) && !rtx_equal_p (operands[0], operands[1])) || reg_mentioned_p (operands[0], operands[1])) @@ -4240,7 +4249,7 @@ operands[5] = operands[1]; /* Apply the operation on D. */ - operands[6] = gen_rtx (REG, QImode, HARD_D_REGNUM); + operands[6] = gen_rtx_REG (QImode, HARD_D_REGNUM); } else { @@ -4283,7 +4292,7 @@ output_asm_insn (\"comb\\n\\tcoma\\n\\tinx\\n\\txgdx\", operands); output_asm_insn (\"bne\\t%l0\", ops); output_asm_insn (\"inx\", operands); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); return \"\"; }") @@ -4395,19 +4404,13 @@ } }") -(define_insn "*ashldi3_const32" +(define_insn_and_split "*ashldi3_const32" [(set (match_operand:DI 0 "nonimmediate_operand" "=<,m,u") (ashift:DI (match_operand:DI 1 "general_operand" "umi,umi,umi") (const_int 32))) (clobber (match_scratch:HI 2 "=&A,d,d"))] "" - "#") - -(define_split - [(set (match_operand:DI 0 "nonimmediate_operand" "") - (ashift:DI (match_operand:DI 1 "general_operand" "") - (const_int 32))) - (clobber (match_scratch:HI 2 ""))] + "#" "reload_completed" [(const_int 0)] "/* Move the lowpart in the highpart first in case the shift @@ -4416,6 +4419,13 @@ { m68hc11_split_move (m68hc11_gen_lowpart (SImode, operands[0]), const0_rtx, operands[2]); + + /* Adjust first operand if it uses SP so that we take into + account the above push. Can occur only for 68HC12. */ + if (reg_mentioned_p (gen_rtx_REG (HImode, HARD_SP_REGNUM), + operands[1])) + operands[1] = adjust_address (operands[1], + GET_MODE (operands[0]), 4); } m68hc11_split_move (m68hc11_gen_highpart (SImode, operands[0]), m68hc11_gen_lowpart (SImode, operands[1]), @@ -4427,34 +4437,34 @@ } DONE;") -(define_insn "*ashldi3_const1" +(define_insn_and_split "*ashldi3_const1" [(set (match_operand:DI 0 "non_push_operand" "=m,m,u") (ashift:DI (match_operand:DI 1 "general_operand" "mi,u,umi") (const_int 1))) (clobber (match_scratch:HI 2 "=d,d,d"))] "" - "#") - -(define_split - [(set (match_operand:DI 0 "non_push_operand" "") - (ashift:DI (match_operand:DI 1 "general_operand" "") - (const_int 1))) - (clobber (match_scratch:HI 2 ""))] + "#" "z_replacement_completed == 2" [(set (match_dup 2) (match_dup 3)) (set (match_dup 2) (ashift:HI (match_dup 2) (const_int 1))) (set (match_dup 4) (match_dup 2)) (set (match_dup 2) (match_dup 5)) - (set (match_dup 2) (rotate:HI (match_dup 2) (reg:HI CC_REGNUM))) + (parallel [(set (match_dup 2) + (rotate:HI (match_dup 2) (const_int 1))) + (clobber (reg:HI CC_REGNUM))]) (set (match_dup 6) (match_dup 2)) (set (match_dup 2) (match_dup 7)) - (set (match_dup 2) (rotate:HI (match_dup 2) (reg:HI CC_REGNUM))) + (parallel [(set (match_dup 2) + (rotate:HI (match_dup 2) (const_int 1))) + (clobber (reg:HI CC_REGNUM))]) (set (match_dup 8) (match_dup 2)) (set (match_dup 2) (match_dup 9)) - (set (match_dup 2) (rotate:HI (match_dup 2) (reg:HI CC_REGNUM))) + (parallel [(set (match_dup 2) + (rotate:HI (match_dup 2) (const_int 1))) + (clobber (reg:HI CC_REGNUM))]) (set (match_dup 10) (match_dup 2))] "operands[3] = m68hc11_gen_lowpart (SImode, operands[1]); operands[5] = m68hc11_gen_highpart (HImode, operands[3]); @@ -4473,10 +4483,10 @@ operands[8] = m68hc11_gen_lowpart (HImode, operands[8]);") (define_insn "addsi_silshr16" - [(set (match_operand:SI 0 "register_operand" "=D,D") - (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "!*uim,0") + [(set (match_operand:SI 0 "register_operand" "=D,D,!D") + (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "!*uim,0,0") (const_int 16)) - (match_operand:SI 2 "general_operand" "0,m!*u")))] + (match_operand:SI 2 "general_operand" "0,m!*u,0")))] "" "#") @@ -4498,14 +4508,24 @@ (const_int 16)) (match_operand:SI 2 "general_operand" "")))] "z_replacement_completed == 2 && X_REG_P (operands[1])" - [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM)) + [(set (reg:HI D_REGNUM) (match_dup 5)) (set (reg:HI X_REGNUM) (match_dup 3)) (set (reg:HI D_REGNUM) (plus:HI (reg:HI D_REGNUM) (match_dup 4))) (set (reg:HI X_REGNUM) (plus:HI (plus:HI (reg:HI X_REGNUM) (const_int 0)) (reg:HI CC_REGNUM)))] "operands[3] = m68hc11_gen_highpart (HImode, operands[2]); - operands[4] = m68hc11_gen_lowpart (HImode, operands[2]);") + if (X_REG_P (operands[2])) + { + operands[4] = gen_rtx_REG (HImode, HARD_X_REGNUM); + operands[5] = gen_rtx_REG (HImode, HARD_D_REGNUM); + } + else + { + operands[4] = m68hc11_gen_lowpart (HImode, operands[2]); + operands[5] = gen_rtx_REG (HImode, HARD_X_REGNUM); + } +") (define_insn "addsi_ashift16" [(set (match_operand:SI 0 "register_operand" "=D") @@ -4531,19 +4551,13 @@ operands[4] = m68hc11_gen_lowpart (HImode, operands[2]); }") -(define_insn "addsi_andshr16" +(define_insn_and_split "addsi_andshr16" [(set (match_operand:SI 0 "register_operand" "=D") (plus:SI (and:SI (match_operand:SI 1 "general_operand" "%uim") (const_int 65535)) (match_operand:SI 2 "general_operand" "0")))] "" - "#") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (and:SI (match_operand:SI 1 "general_operand" "") - (const_int 65535)) - (match_operand:SI 2 "general_operand" "")))] + "#" "z_replacement_completed == 2" [(set (reg:HI D_REGNUM) (plus:HI (reg:HI D_REGNUM) (match_dup 3))) (set (reg:HI X_REGNUM) (plus:HI (plus:HI (reg:HI X_REGNUM) (const_int 0)) (reg:HI CC_REGNUM)))] @@ -4590,31 +4604,24 @@ "" "#") -(define_insn "*ashlsi3_const16_zexthi" +(define_insn_and_split "*ashlsi3_const16_zexthi" [(set (match_operand:SI 0 "nonimmediate_operand" "=D") (ashift:SI (zero_extend:HI (match_operand:HI 1 "general_operand" "duim*A")) (const_int 16))) (clobber (match_scratch:HI 2 "=X"))] "" - "#") - -(define_split /* "*ashlsi3_const16_zexthi"*/ - [(set (match_operand:SI 0 "nonimmediate_operand" "") - (ashift:SI (zero_extend:HI - (match_operand:HI 1 "general_operand" "")) - (const_int 16))) - (clobber (match_scratch:HI 2 "=X"))] + "#" "reload_completed" [(set (reg:HI X_REGNUM) (match_dup 1)) (set (reg:HI D_REGNUM) (const_int 0))] "") (define_insn "*ashlsi3_const1" - [(set (match_operand:SI 0 "non_push_operand" "=D,D,m,!*u,?*um") - (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,*um,0,0,*um") + [(set (match_operand:SI 0 "non_push_operand" "=D,D,D,m,*u,*u") + (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,*u,m,*u,m") (const_int 1))) - (clobber (match_scratch:HI 2 "=X,X,&d,&d,&d"))] + (clobber (match_scratch:HI 2 "=X,X,X,&d,&d,&d"))] "" "* { @@ -4628,7 +4635,7 @@ rtx ops[2]; ops[1] = m68hc11_gen_lowpart (HImode, operands[1]); - ops[0] = gen_rtx (REG, HImode, HARD_D_REGNUM); + ops[0] = gen_rtx_REG (HImode, HARD_D_REGNUM); m68hc11_gen_movhi (insn, ops); output_asm_insn (\"lsld\", ops); if (!X_REG_P (operands[0])) @@ -4644,7 +4651,7 @@ { /* Load the high part in X in case the source operand uses X as a memory pointer. */ - ops[0] = gen_rtx (REG, HImode, HARD_X_REGNUM); + ops[0] = gen_rtx_REG (HImode, HARD_X_REGNUM); ops[1] = m68hc11_gen_highpart (HImode, operands[1]); m68hc11_gen_movhi (insn, ops); output_asm_insn (\"xgdx\", ops); @@ -4670,7 +4677,7 @@ (ashift:SI (match_dup 0) (match_operand:HI 1 "const_int_operand" ""))) (clobber (match_scratch:HI 2 "=y"))] - "" + "TARGET_M6811 /* See *ashlsi3 note. */" "* { CC_STATUS_INIT; @@ -4680,7 +4687,7 @@ (define_insn "*ashlsi3" [(set (match_operand:SI 0 "register_operand" "+D,D") (ashift:SI (match_dup 0) - (match_operand:HI 1 "general_operand" "y,m"))) + (match_operand:HI 1 "general_operand" "y,mi"))) (clobber (match_scratch:HI 2 "=1,X"))] "" "* @@ -4693,7 +4700,12 @@ is not enough register in class A_REGS. Assuming that 'operands[1]' does not refer to the stack (which - is true for 68hc11 only, we save temporary the value of Y. */ + is true for 68hc11 only, we save temporary the value of Y. + + For 68HC12 we must also accept a constant because Z register is + disabled when compiling with -fomit-frame-pointer. We can come up + with a reload problem and the *lshrsi3_const pattern was disabled + for that reason. */ if (!Y_REG_P (operands[2])) { rtx ops[1]; @@ -4724,12 +4736,12 @@ { rtx scratch = gen_reg_rtx (HImode); emit_move_insn (scratch, operands[2]); - emit_insn (gen_rtx (PARALLEL, VOIDmode, - gen_rtvec (2, gen_rtx (SET, VOIDmode, + emit_insn (gen_rtx_PARALLEL (VOIDmode, + gen_rtvec (2, gen_rtx_SET (VOIDmode, operand0, gen_rtx_ASHIFT (HImode, operand1, scratch)), - gen_rtx (CLOBBER, VOIDmode, scratch)))); + gen_rtx_CLOBBER (VOIDmode, scratch)))); DONE; } }") @@ -4757,13 +4769,16 @@ (define_insn "*ashlhi3_2" - [(set (match_operand:HI 0 "register_operand" "=d") - (ashift:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "register_operand" "+x"))) + [(set (match_operand:HI 0 "register_operand" "=d,*x") + (ashift:HI (match_operand:HI 1 "register_operand" "0,0") + (match_operand:HI 2 "register_operand" "+x,+d"))) (clobber (match_dup 2))] "" "* { + if (A_REG_P (operands[0])) + return \"#\"; + CC_STATUS_INIT; return \"bsr\\t___lshlhi3\"; }") @@ -4914,7 +4929,7 @@ if (!D_REG_P (operands[0]) && !Q_REG_P (operands[0])) return \"#\"; - ops[0] = gen_rtx (REG, QImode, HARD_A_REGNUM); + ops[0] = gen_rtx_REG (QImode, HARD_A_REGNUM); ops[1] = operands[2]; m68hc11_gen_movqi (insn, ops); @@ -4934,12 +4949,12 @@ rtx scratch = gen_reg_rtx (HImode); emit_move_insn (scratch, operands[2]); - emit_insn (gen_rtx (PARALLEL, VOIDmode, - gen_rtvec (2, gen_rtx (SET, VOIDmode, + emit_insn (gen_rtx_PARALLEL (VOIDmode, + gen_rtvec (2, gen_rtx_SET (VOIDmode, operand0, gen_rtx_ASHIFTRT (HImode, operand1, scratch)), - gen_rtx (CLOBBER, VOIDmode, scratch)))); + gen_rtx_CLOBBER (VOIDmode, scratch)))); DONE; } }") @@ -4993,7 +5008,7 @@ output_asm_insn (\"comb\", operands); CC_STATUS_INIT; - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); return \"\"; } @@ -5007,7 +5022,7 @@ output_asm_insn (\"bge\\t%l0\", ops); output_asm_insn (\"deca\", operands); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); val -= 8; @@ -5030,7 +5045,7 @@ output_asm_insn (\"bcc\\t%l0\", ops); output_asm_insn (\"coma\", ops); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); return \"\"; } @@ -5046,21 +5061,17 @@ }") (define_insn "*ashrhi3" - [(set (match_operand:HI 0 "register_operand" "=d,x") + [(set (match_operand:HI 0 "register_operand" "=d,*x") (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0") (match_operand:HI 2 "register_operand" "+x,+d"))) (clobber (match_dup 2))] "" "* { - CC_STATUS_INIT; - if (D_REG_P (operands[2])) - output_asm_insn (\"xgd%0\", operands); + if (A_REG_P (operands[0])) + return \"#\"; output_asm_insn (\"bsr\\t___ashrhi3\", operands); - if (D_REG_P (operands[2])) - output_asm_insn (\"xgd%0\", operands); - return \"\"; }") @@ -5081,7 +5092,7 @@ (ashiftrt:SI (match_dup 0) (match_operand:HI 1 "const_int_operand" ""))) (clobber (match_scratch:HI 2 "=y"))] - "" + "TARGET_M6811 /* See *ashrsi3 note. */" "* { CC_STATUS_INIT; @@ -5091,7 +5102,7 @@ (define_insn "*ashrsi3" [(set (match_operand:SI 0 "register_operand" "+D,D") (ashiftrt:SI (match_dup 0) - (match_operand:HI 1 "general_operand" "y,m"))) + (match_operand:HI 1 "general_operand" "y,mi"))) (clobber (match_scratch:HI 2 "=1,X"))] "" "* @@ -5103,7 +5114,12 @@ is not enough register in class A_REGS. Assuming that 'operands[1]' does not refer to the stack (which - is true for 68hc11 only, we save temporary the value of Y. */ + is true for 68hc11 only, we save temporary the value of Y. + + For 68HC12 we must also accept a constant because Z register is + disabled when compiling with -fomit-frame-pointer. We can come up + with a reload problem and the *lshrsi3_const pattern was disabled + for that reason. */ if (!Y_REG_P (operands[2])) { rtx ops[1]; @@ -5182,7 +5198,7 @@ if (!D_REG_P (operands[0]) && !Q_REG_P (operands[0])) return \"#\"; - ops[0] = gen_rtx (REG, QImode, HARD_A_REGNUM); + ops[0] = gen_rtx_REG (QImode, HARD_A_REGNUM); ops[1] = operands[2]; m68hc11_gen_movqi (insn, ops); @@ -5209,19 +5225,13 @@ } }") -(define_insn "*lshrdi3_const32" +(define_insn_and_split "*lshrdi3_const32" [(set (match_operand:DI 0 "nonimmediate_operand" "=<,m,u") (lshiftrt:DI (match_operand:DI 1 "general_operand" "umi,umi,umi") (const_int 32))) (clobber (match_scratch:HI 2 "=&A,d,d"))] "" - "#") - -(define_split - [(set (match_operand:DI 0 "nonimmediate_operand" "") - (lshiftrt:DI (match_operand:DI 1 "general_operand" "") - (const_int 32))) - (clobber (match_scratch:HI 2 "=&A,d"))] + "#" "reload_completed" [(const_int 0)] "m68hc11_split_move (m68hc11_gen_lowpart (SImode, operands[0]), @@ -5291,34 +5301,31 @@ operands[7] = m68hc11_gen_highpart (HImode, operands[6]); operands[6] = m68hc11_gen_lowpart (HImode, operands[6]);") -(define_insn "*lshrdi_const1" +(define_insn_and_split "*lshrdi_const1" [(set (match_operand:DI 0 "non_push_operand" "=m,u") (lshiftrt:DI (match_operand:DI 1 "general_operand" "umi,umi") (const_int 1))) (clobber (match_scratch:HI 2 "=d,d"))] "" - "#") - -(define_split - [(set (match_operand:DI 0 "non_push_operand" "") - (lshiftrt:DI (match_operand:DI 1 "general_operand" "") - (const_int 1))) - (clobber (match_scratch:HI 2 ""))] + "#" "z_replacement_completed == 2" [(set (match_dup 2) (match_dup 3)) (set (match_dup 2) (lshiftrt:HI (match_dup 2) (const_int 1))) (set (match_dup 4) (match_dup 2)) (set (match_dup 2) (match_dup 5)) - (set (match_dup 2) (rotatert:HI (match_dup 2) (reg:HI CC_REGNUM))) + (parallel [(set (match_dup 2) (rotatert:HI (match_dup 2) (const_int 1))) + (clobber (reg:HI CC_REGNUM))]) (set (match_dup 6) (match_dup 2)) (set (match_dup 2) (match_dup 7)) - (set (match_dup 2) (rotatert:HI (match_dup 2) (reg:HI CC_REGNUM))) + (parallel [(set (match_dup 2) (rotatert:HI (match_dup 2) (const_int 1))) + (clobber (reg:HI CC_REGNUM))]) (set (match_dup 8) (match_dup 2)) (set (match_dup 2) (match_dup 9)) - (set (match_dup 2) (rotatert:HI (match_dup 2) (reg:HI CC_REGNUM))) + (parallel [(set (match_dup 2) (rotatert:HI (match_dup 2) (const_int 1))) + (clobber (reg:HI CC_REGNUM))]) (set (match_dup 10) (match_dup 2))] "operands[3] = m68hc11_gen_highpart (SImode, operands[1]); operands[5] = m68hc11_gen_lowpart (HImode, operands[3]); @@ -5373,10 +5380,10 @@ #") (define_insn "*lshrsi3_const1" - [(set (match_operand:SI 0 "non_push_operand" "=D,m,*u") - (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "D*um,*um,*um") + [(set (match_operand:SI 0 "non_push_operand" "=D,D,D,m,*u,*u") + (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,*u,m,*u,m") (const_int 1))) - (clobber (match_scratch:HI 2 "=X,&d,&d"))] + (clobber (match_scratch:HI 2 "=X,X,X,&d,&d,&d"))] "" "* { @@ -5390,7 +5397,7 @@ rtx ops[2]; ops[1] = m68hc11_gen_highpart (HImode, operands[1]); - ops[0] = gen_rtx (REG, HImode, HARD_D_REGNUM); + ops[0] = gen_rtx_REG (HImode, HARD_D_REGNUM); m68hc11_gen_movhi (insn, ops); output_asm_insn (\"lsrd\", ops); if (!X_REG_P (operands[0])) @@ -5405,7 +5412,7 @@ else { /* Load the lowpart in X in case the operands is some N,x. */ - ops[0] = gen_rtx (REG, HImode, HARD_X_REGNUM); + ops[0] = gen_rtx_REG (HImode, HARD_X_REGNUM); ops[1] = m68hc11_gen_lowpart (HImode, operands[1]); m68hc11_gen_movhi (insn, ops); output_asm_insn (\"xgdx\", ops); @@ -5427,7 +5434,7 @@ (lshiftrt:SI (match_dup 0) (match_operand:HI 1 "const_int_operand" ""))) (clobber (match_scratch:HI 2 "=y"))] - "" + "TARGET_M6811 /* See *lshrsi3 note. */" "* { CC_STATUS_INIT; @@ -5437,7 +5444,7 @@ (define_insn "*lshrsi3" [(set (match_operand:SI 0 "register_operand" "+D,D") (lshiftrt:SI (match_dup 0) - (match_operand:HI 1 "general_operand" "y,m"))) + (match_operand:HI 1 "general_operand" "y,mi"))) (clobber (match_scratch:HI 2 "=1,X"))] "" "* @@ -5449,7 +5456,12 @@ is not enough register in class A_REGS. Assuming that 'operands[1]' does not refer to the stack (which - is true for 68hc11 only, we save temporary the value of Y. */ + is true for 68hc11 only, we save temporary the value of Y. + + For 68HC12 we must also accept a constant because Z register is + disabled when compiling with -fomit-frame-pointer. We can come up + with a reload problem and the *lshrsi3_const pattern was disabled + for that reason. */ if (!Y_REG_P (operands[2])) { rtx ops[1]; @@ -5482,12 +5494,12 @@ operand1 = force_reg (HImode, operand1); emit_move_insn (scratch, operands[2]); - emit_insn (gen_rtx (PARALLEL, VOIDmode, - gen_rtvec (2, gen_rtx (SET, VOIDmode, + emit_insn (gen_rtx_PARALLEL (VOIDmode, + gen_rtvec (2, gen_rtx_SET (VOIDmode, operand0, gen_rtx_LSHIFTRT (HImode, operand1, scratch)), - gen_rtx (CLOBBER, VOIDmode, scratch)))); + gen_rtx_CLOBBER (VOIDmode, scratch)))); DONE; } }") @@ -5594,22 +5606,17 @@ }") (define_insn "*lshrhi3" - [(set (match_operand:HI 0 "register_operand" "=d,x") + [(set (match_operand:HI 0 "register_operand" "=d,*x") (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0") (match_operand:HI 2 "register_operand" "+x,+d"))) (clobber (match_dup 2))] "" "* { - CC_STATUS_INIT; - if (D_REG_P (operands[2])) - output_asm_insn (\"xgd%0\", operands); - - output_asm_insn (\"bsr\\t___lshrhi3\", operands); - if (D_REG_P (operands[2])) - output_asm_insn (\"xgd%0\", operands); + if (A_REG_P (operands[0])) + return \"#\"; - return \"\"; + return \"bsr\\t___lshrhi3\"; }") (define_expand "lshrqi3" @@ -5709,7 +5716,7 @@ return \"#\"; CC_STATUS_INIT; - ops[0] = gen_rtx (REG, QImode, HARD_A_REGNUM); + ops[0] = gen_rtx_REG (QImode, HARD_A_REGNUM); ops[1] = operands[2]; m68hc11_gen_movqi (insn, ops); @@ -5722,14 +5729,14 @@ ops[1] = gen_label_rtx (); output_asm_insn (\"ble\\t%l1\", ops); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); output_asm_insn (\"lsrb\", operands); output_asm_insn (\"deca\", operands); output_asm_insn (\"bne\\t%l0\", ops); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[1])); return \"\"; }") @@ -5750,7 +5757,8 @@ (define_insn "*rotlhi3_with_carry" [(set (match_operand:HI 0 "register_operand" "=d") (rotate:HI (match_operand:HI 1 "register_operand" "0") - (reg:HI CC_REGNUM)))] + (const_int 1))) + (clobber (reg:HI CC_REGNUM))] "" "* { @@ -5761,7 +5769,8 @@ (define_insn "*rotrhi3_with_carry" [(set (match_operand:HI 0 "register_operand" "=d") (rotatert:HI (match_operand:HI 1 "register_operand" "0") - (reg:HI CC_REGNUM)))] + (const_int 1))) + (clobber (reg:HI CC_REGNUM))] "" "* { @@ -5780,7 +5789,41 @@ return \"\"; }") -(define_insn "rotlhi3" +(define_insn "rotrqi3" + [(set (match_operand:QI 0 "register_operand" "=d,!q") + (rotatert:QI (match_operand:QI 1 "register_operand" "0,0") + (match_operand:QI 2 "const_int_operand" "i,i")))] + "" + "* +{ + m68hc11_gen_rotate (ROTATERT, insn, operands); + return \"\"; +}") + +(define_expand "rotlhi3" + [(set (match_operand:HI 0 "register_operand" "") + (rotate:HI (match_operand:HI 1 "register_operand" "") + (match_operand:HI 2 "general_operand" "")))] + "" + " +{ + if (GET_CODE (operands[2]) != CONST_INT) + { + rtx scratch = gen_reg_rtx (HImode); + operand1 = force_reg (HImode, operand1); + + emit_move_insn (scratch, operands[2]); + emit_insn (gen_rtx_PARALLEL (VOIDmode, + gen_rtvec (2, gen_rtx_SET (VOIDmode, + operand0, + gen_rtx_ROTATE (HImode, + operand1, scratch)), + gen_rtx_CLOBBER (VOIDmode, scratch)))); + DONE; + } +}") + +(define_insn "rotlhi3_const" [(set (match_operand:HI 0 "register_operand" "=d") (rotate:HI (match_operand:HI 1 "register_operand" "0") (match_operand:HI 2 "const_int_operand" "i")))] @@ -5791,18 +5834,44 @@ return \"\"; }") -(define_insn "rotrqi3" - [(set (match_operand:QI 0 "register_operand" "=d,!q") - (rotatert:QI (match_operand:QI 1 "register_operand" "0,0") - (match_operand:QI 2 "const_int_operand" "i,i")))] +(define_insn "*rotlhi3" + [(set (match_operand:HI 0 "register_operand" "=d,*x") + (rotate:HI (match_operand:HI 1 "register_operand" "0,0") + (match_operand:HI 2 "general_operand" "+x,+d"))) + (clobber (match_dup 2))] "" "* { - m68hc11_gen_rotate (ROTATERT, insn, operands); - return \"\"; + if (A_REG_P (operands[0])) + return \"#\"; + + return \"bsr\\t___rotlhi3\"; }") -(define_insn "rotrhi3" +(define_expand "rotrhi3" + [(set (match_operand:HI 0 "register_operand" "") + (rotatert:HI (match_operand:HI 1 "general_operand" "") + (match_operand:HI 2 "general_operand" "")))] + "" + " +{ + if (GET_CODE (operands[2]) != CONST_INT) + { + rtx scratch = gen_reg_rtx (HImode); + operand1 = force_reg (HImode, operand1); + + emit_move_insn (scratch, operands[2]); + emit_insn (gen_rtx_PARALLEL (VOIDmode, + gen_rtvec (2, gen_rtx_SET (VOIDmode, + operand0, + gen_rtx_ROTATERT (HImode, + operand1, scratch)), + gen_rtx_CLOBBER (VOIDmode, scratch)))); + DONE; + } +}") + +(define_insn "rotrhi3_const" [(set (match_operand:HI 0 "register_operand" "=d") (rotatert:HI (match_operand:HI 1 "register_operand" "0") (match_operand:HI 2 "const_int_operand" "i")))] @@ -5813,6 +5882,249 @@ return \"\"; }") +(define_insn "*rotrhi3" + [(set (match_operand:HI 0 "register_operand" "=d,*x") + (rotatert:HI (match_operand:HI 1 "register_operand" "0,0") + (match_operand:HI 2 "general_operand" "+x,+d"))) + (clobber (match_dup 2))] + "" + "* +{ + if (A_REG_P (operands[0])) + return \"#\"; + + return \"bsr\\t___rotrhi3\"; +}") + +;; Split a shift operation on an address register in a shift +;; on D_REGNUM. +(define_split /* "*rotrhi3_addr" */ + [(set (match_operand:HI 0 "hard_addr_reg_operand" "") + (match_operator:HI 3 "m68hc11_shift_operator" + [(match_operand:HI 1 "register_operand" "") + (match_operand:HI 2 "register_operand" "")])) + (clobber (match_dup 2))] + "z_replacement_completed == 2" + [(parallel [(set (reg:HI D_REGNUM) (match_dup 0)) + (set (match_dup 0) (reg:HI D_REGNUM))]) + (parallel [(set (reg:HI D_REGNUM) + (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 0)])) + (clobber (match_dup 0))]) + (parallel [(set (reg:HI D_REGNUM) (match_dup 0)) + (set (match_dup 0) (reg:HI D_REGNUM))])] + "") + +;;-------------------------------------------------------------------- +;;- 68HC12 Decrement/Increment and branch +;;-------------------------------------------------------------------- +;; These patterns are used by loop optimization as well as peephole2 +;; They must handle reloading themselves and the scratch register +;; is used for that. Even if we accept memory operand, we must not +;; accept them on the predicate because it might create too many reloads. +;; (specially on HC12 due to its auto-incdec addressing modes). +;; +(define_expand "decrement_and_branch_until_zero" + [(parallel [(set (pc) + (if_then_else + (ne (plus:HI (match_operand:HI 0 "register_operand" "") + (const_int 0)) + (const_int 1)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:HI (match_dup 0) + (const_int -1))) + (clobber (match_scratch:HI 2 ""))])] + "TARGET_M6812" + "") + +(define_expand "doloop_end" + [(use (match_operand 0 "" "")) ; loop pseudo + (use (match_operand 1 "" "")) ; iterations; zero if unknown + (use (match_operand 2 "" "")) ; max iterations + (use (match_operand 3 "" "")) ; loop level + (use (match_operand 4 "" ""))] ; label + "TARGET_M6812" + " +{ + /* Reject non-constant loops as it generates bigger code due to + the handling of the loop register. We can do better by using + the peephole2 dbcc/ibcc patterns. */ + if (INTVAL (operands[1]) == 0) + { + FAIL; + } + + /* Note that for xxx_dbcc_dec_yy the gen_rtx_NE is only used to pass + the operator and its operands are not relevant. */ + if (GET_MODE (operands[0]) == HImode) + { + emit_jump_insn (gen_m68hc12_dbcc_dec_hi (operands[0], + gen_rtx_NE (HImode, + operands[0], + const1_rtx), + operands[4])); + DONE; + } + if (GET_MODE (operands[0]) == QImode) + { + emit_jump_insn (gen_m68hc12_dbcc_dec_qi (operands[0], + gen_rtx_NE (QImode, + operands[0], + const1_rtx), + operands[4])); + DONE; + } + + FAIL; +}") + +;; Decrement-and-branch insns. +(define_insn "m68hc12_dbcc_dec_hi" + [(set (pc) + (if_then_else + (match_operator 1 "m68hc11_eq_compare_operator" + [(match_operand:HI 0 "register_operand" "+dxy,m*u*z") + (const_int 1)]) + (label_ref (match_operand 2 "" "")) + (pc))) + (set (match_dup 0) + (plus:HI (match_dup 0) (const_int -1))) + (clobber (match_scratch:HI 3 "=X,dxy"))] + "TARGET_M6812" + "* +{ + if (!H_REG_P (operands[0])) + return \"#\"; + + CC_STATUS_INIT; + if (GET_CODE (operands[1]) == EQ) + return \"dbeq\\t%0,%l2\"; + else + return \"dbne\\t%0,%l2\"; +}") + +;; Decrement-and-branch insns. +(define_insn "m68hc12_dbcc_inc_hi" + [(set (pc) + (if_then_else + (match_operator 1 "m68hc11_eq_compare_operator" + [(match_operand:HI 0 "register_operand" "+dxy,m*u*z") + (const_int -1)]) + (label_ref (match_operand 2 "" "")) + (pc))) + (set (match_dup 0) + (plus:HI (match_dup 0) (const_int 1))) + (clobber (match_scratch:HI 3 "=X,dxy"))] + "TARGET_M6812" + "* +{ + if (!H_REG_P (operands[0])) + return \"#\"; + + CC_STATUS_INIT; + if (GET_CODE (operands[1]) == EQ) + return \"ibeq\\t%0,%l2\"; + else + return \"ibeq\\t%0,%l2\"; +}") + +;; Decrement-and-branch (QImode). +(define_insn "m68hc12_dbcc_dec_qi" + [(set (pc) + (if_then_else + (match_operator 1 "m68hc11_eq_compare_operator" + [(match_operand:QI 0 "register_operand" "+d,m*u*A") + (const_int 1)]) + (label_ref (match_operand 2 "" "")) + (pc))) + (set (match_dup 0) + (plus:QI (match_dup 0) (const_int -1))) + (clobber (match_scratch:QI 3 "=X,d"))] + "TARGET_M6812" + "* +{ + if (!D_REG_P (operands[0])) + return \"#\"; + + CC_STATUS_INIT; + if (GET_CODE (operands[1]) == EQ) + return \"dbeq\\tb,%l2\"; + else + return \"dbne\\tb,%l2\"; +}") + +;; Increment-and-branch (QImode). +(define_insn "m68hc12_dbcc_inc_qi" + [(set (pc) + (if_then_else + (match_operator 1 "m68hc11_eq_compare_operator" + [(match_operand:QI 0 "register_operand" "+d,m*u*A") + (const_int -1)]) + (label_ref (match_operand 2 "" "")) + (pc))) + (set (match_dup 0) + (plus:QI (match_dup 0) (const_int 1))) + (clobber (match_scratch:QI 3 "=X,d"))] + "TARGET_M6812" + "* +{ + if (!D_REG_P (operands[0])) + return \"#\"; + + CC_STATUS_INIT; + if (GET_CODE (operands[1]) == EQ) + return \"ibeq\\tb,%l2\"; + else + return \"ibeq\\tb,%l2\"; +}") + +;; Split the above to handle the case where operand 0 is in memory +;; (a register that couldn't get a hard register) +(define_split + [(set (pc) + (if_then_else + (match_operator 3 "m68hc11_eq_compare_operator" + [(match_operand:HI 0 "general_operand" "") + (match_operand:HI 1 "const_int_operand" "")]) + (label_ref (match_operand 4 "" "")) + (pc))) + (set (match_dup 0) + (plus:HI (match_dup 0) (match_operand 2 "const_int_operand" ""))) + (clobber (match_operand:HI 5 "hard_reg_operand" ""))] + "TARGET_M6812 && reload_completed" + [(set (match_dup 5) (match_dup 0)) + (set (match_dup 5) (plus:HI (match_dup 5) (match_dup 2))) + (set (match_dup 0) (match_dup 5)) + (set (pc) + (if_then_else (match_op_dup 3 + [(match_dup 5) (const_int 0)]) + (label_ref (match_dup 4)) (pc)))] + "") + +;; Split the above to handle the case where operand 0 is in memory +;; (a register that couldn't get a hard register) +(define_split + [(set (pc) + (if_then_else + (match_operator 3 "m68hc11_eq_compare_operator" + [(match_operand:QI 0 "general_operand" "") + (match_operand:QI 1 "const_int_operand" "")]) + (label_ref (match_operand 4 "" "")) + (pc))) + (set (match_dup 0) + (plus:QI (match_dup 0) (match_operand 2 "const_int_operand" ""))) + (clobber (match_operand:QI 5 "hard_reg_operand" ""))] + "TARGET_M6812 && reload_completed" + [(set (match_dup 5) (match_dup 0)) + (set (match_dup 5) (plus:QI (match_dup 5) (match_dup 2))) + (set (match_dup 0) (match_dup 5)) + (set (pc) + (if_then_else (match_op_dup 3 + [(match_dup 5) (const_int 0)]) + (label_ref (match_dup 4)) (pc)))] + "") + ;;-------------------------------------------------------------------- ;;- Jumps and transfers ;;-------------------------------------------------------------------- @@ -6281,7 +6593,22 @@ { if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) { - if (SYMBOL_REF_FLAG (XEXP (operands[0], 0)) == 1) + if (m68hc11_is_far_symbol (operands[0])) + { + if (TARGET_M6812) + { + output_asm_insn (\"call\\t%0\", operands); + return \"\"; + } + else + { + output_asm_insn (\"pshb\", operands); + output_asm_insn (\"ldab\\t#%%page(%0)\", operands); + output_asm_insn (\"ldy\\t#%%addr(%0)\", operands); + return \"jsr\\t__call_a32\"; + } + } + if (m68hc11_is_trap_symbol (operands[0])) return \"swi\"; else return \"bsr\\t%0\"; @@ -6301,7 +6628,22 @@ { if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) { - if (SYMBOL_REF_FLAG (XEXP (operands[1], 0)) == 1) + if (m68hc11_is_far_symbol (operands[1])) + { + if (TARGET_M6812) + { + output_asm_insn (\"call\\t%1\", operands); + return \"\"; + } + else + { + output_asm_insn (\"pshb\", operands); + output_asm_insn (\"ldab\\t#%%page(%1)\", operands); + output_asm_insn (\"ldy\\t#%%addr(%1)\", operands); + return \"jsr\\t__call_a32\"; + } + } + if (m68hc11_is_trap_symbol (operands[1])) return \"swi\"; else return \"bsr\\t%1\"; @@ -6380,8 +6722,8 @@ { int ret_size = 0; - if (current_function_return_rtx) - ret_size = GET_MODE_SIZE (GET_MODE (current_function_return_rtx)); + if (crtl->return_rtx) + ret_size = GET_MODE_SIZE (GET_MODE (crtl->return_rtx)); /* Emit use notes only when HAVE_return is true. */ if (m68hc11_total_frame_size () != 0) @@ -6389,7 +6731,7 @@ if (ret_size && ret_size <= 2) { - emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, + emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, gen_rtx_RETURN (VOIDmode), gen_rtx_USE (VOIDmode, gen_rtx_REG (HImode, 1))))); @@ -6397,7 +6739,7 @@ } if (ret_size) { - emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, + emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, gen_rtx_RETURN (VOIDmode), gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 0))))); @@ -6418,7 +6760,25 @@ return \"\"; if (current_function_interrupt || current_function_trap) return \"rti\"; - return \"rts\"; + else if (!current_function_far) + return \"rts\"; + else if (TARGET_M6812) + return \"rtc\"; + else + { + int ret_size = 0; + + if (crtl->return_rtx) + ret_size = GET_MODE_SIZE (GET_MODE (crtl->return_rtx)); + + if (ret_size == 0) + return \"jmp\\t__return_void\"; + if (ret_size <= 2) + return \"jmp\\t__return_16\"; + if (ret_size <= 4) + return \"jmp\\t__return_32\"; + return \"jmp\\t__return_16\"; + } }") (define_insn "*return_16bit" @@ -6435,7 +6795,12 @@ return \"\"; if (current_function_interrupt || current_function_trap) return \"rti\"; - return \"rts\"; + else if (!current_function_far) + return \"rts\"; + else if (TARGET_M6812) + return \"rtc\"; + else + return \"jmp\\t__return_16\"; }") (define_insn "*return_32bit" @@ -6452,7 +6817,12 @@ return \"\"; if (current_function_interrupt || current_function_trap) return \"rti\"; - return \"rts\"; + else if (!current_function_far) + return \"rts\"; + else if (TARGET_M6812) + return \"rtc\"; + else + return \"jmp\\t__return_32\"; }") (define_insn "indirect_jump" @@ -6484,21 +6854,140 @@ ;;- Peepholes ;;-------------------------------------------------------------------- +;;-------------------------------------------------------------------- +;;- 68HC12 dbcc/ibcc peepholes +;;-------------------------------------------------------------------- +;; +;; Replace: "addd #-1; bne L1" into "dbne d,L1" +;; "addd #-1; beq L1" into "dbeq d,L1" +;; "addd #1; bne L1" into "ibne d,L1" +;; "addd #1; beq L1" into "ibeq d,L1" +;; +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (plus:HI (match_dup 0) + (match_operand:HI 1 "const_int_operand" ""))) + (set (pc) + (if_then_else (match_operator 2 "m68hc11_eq_compare_operator" + [(match_dup 0) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) (pc)))] + "TARGET_M6812 && (INTVAL (operands[1]) == 1 || INTVAL (operands[1]) == -1)" + [(parallel [ + (set (pc) (if_then_else (match_op_dup 2 [(match_dup 0) (match_dup 5)]) + (label_ref (match_dup 3)) (pc))) + (set (match_dup 0) (plus:HI (match_dup 0) (match_dup 1))) + (clobber (match_dup 4))])] + "operands[4] = gen_rtx_SCRATCH(HImode); + operands[5] = GEN_INT (-INTVAL (operands[1]));") + + +;; +;; Replace: "addb #-1; bne L1" into "dbne b,L1" +;; "addb #-1; beq L1" into "dbeq b,L1" +;; +(define_peephole2 + [(set (match_operand:QI 0 "hard_reg_operand" "") + (plus:QI (match_dup 0) + (match_operand:QI 1 "const_int_operand" ""))) + (set (pc) + (if_then_else (match_operator 2 "m68hc11_eq_compare_operator" + [(match_dup 0) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) (pc)))] + "TARGET_M6812 && D_REG_P (operands[0]) + && (INTVAL (operands[1]) == 1 || INTVAL (operands[1]) == -1)" + [(parallel [ + (set (pc) (if_then_else (match_op_dup 2 [(match_dup 0) (match_dup 5)]) + (label_ref (match_dup 3)) (pc))) + (set (match_dup 0) (plus:QI (match_dup 0) (match_dup 1))) + (clobber (match_dup 4))])] + "operands[4] = gen_rtx_SCRATCH(QImode); + operands[5] = GEN_INT (-INTVAL (operands[1]));") + + +;;-------------------------------------------------------------------- +;;- Move peephole2 +;;-------------------------------------------------------------------- + ;; ;; Replace "leas 2,sp" with a "pulx" or a "puly". ;; On 68HC12, this is one cycle slower but one byte smaller. -;; pr target/6899: This peephole is not valid because a register CSE -;; pass removes the pulx/puly. +;; pr target/6899: This peephole was not valid because a register CSE +;; pass removes the pulx/puly. The 'use' clause ensure that the pulx is +;; not removed. ;; (define_peephole2 [(set (reg:HI SP_REGNUM) (plus:HI (reg:HI SP_REGNUM) (const_int 2))) (match_scratch:HI 0 "xy")] - "0 && TARGET_M6812 && optimize_size" - [(set (match_dup 0) (match_dup 1))] - "operands[1] = gen_rtx (MEM, HImode, - gen_rtx (POST_INC, HImode, + "TARGET_M6812 && optimize_size" + [(set (match_dup 0) (match_dup 1)) + (use (match_dup 0))] + "operands[1] = gen_rtx_MEM (HImode, + gen_rtx_POST_INC (HImode, gen_rtx_REG (HImode, HARD_SP_REGNUM)));") +;; Replace: "pshx; tfr d,x; stx 0,sp" into "pshd; tfr d,x" +;; +;; PR 14542: emit a use to pretend we need the value of initial register. +;; Otherwise verify_local_live_at_start will die due to a live change +;; of that register. +;; +(define_peephole2 + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) + (match_operand:HI 0 "hard_reg_operand" "")) + (set (match_dup 0) + (match_operand:HI 1 "hard_reg_operand" "")) + (set (mem:HI (reg:HI SP_REGNUM)) + (match_dup 0))] + "TARGET_M6812" + [(use (match_dup 0)) + (set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) + (match_dup 1)) + (set (match_dup 0) (match_dup 1))] + "") + +;; +;; Change: "ldd 0,sp; pulx" into "puld" +;; This sequence usually appears at end a functions. +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (mem:HI (reg:HI SP_REGNUM))) + (use (match_dup 0)) + (set (match_operand:HI 1 "hard_reg_operand" "") + (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))] + "peep2_reg_dead_p (2, operands[1])" + [(set (match_dup 0) (mem:HI (post_inc:HI (reg:HI SP_REGNUM)))) + (use (match_dup 0))] + "") + +;; Replace: "pshx; clr 0,sp; clr 1,sp" by "clr 1,-sp; clr 1,-sp" +;; Appears to allocate local variables. +(define_peephole2 + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) + (match_operand:HI 0 "hard_reg_operand" "")) + (set (mem:QI (plus:HI (reg:HI SP_REGNUM) (const_int 1))) + (const_int 0)) + (set (mem:QI (reg:HI SP_REGNUM)) + (const_int 0))] + "TARGET_M6812" + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) + (const_int 0))] + "") + +;; Likewise for HI mode +(define_peephole2 + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) + (match_operand:HI 0 "hard_reg_operand" "")) + (set (mem:HI (reg:HI SP_REGNUM)) + (const_int 0))] + "TARGET_M6812" + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) + (const_int 0))] + "") +;;-------------------------------------------------------------------- +;;- +;;-------------------------------------------------------------------- ;; ;; Optimize memory<->memory moves when the value is also loaded in ;; a register. @@ -6543,8 +7032,7 @@ (set (match_operand:HI 2 "hard_reg_operand" "") (match_dup 1))] "(D_REG_P (operands[2]) || X_REG_P (operands[2]) || Y_REG_P (operands[2])) - && !reg_mentioned_p (operands[2], operands[0]) - && GET_MODE (operands[2]) == HImode" + && !reg_mentioned_p (operands[2], operands[0])" [(set (match_dup 2) (match_dup 1)) (set (match_dup 0) (match_dup 2))] "") @@ -6563,6 +7051,36 @@ (set (match_dup 0) (plus:HI (match_dup 0) (match_dup 1)))] "") +;; +;; Replace: "ldx #N; xgdx; addd ; xgdx" by "ldab #N; ldx ; abx" +;; +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "const_int_operand" "")) + (set (match_dup 0) + (plus:HI (match_dup 0) + (match_operand:HI 2 "general_operand" ""))) + (match_scratch:QI 3 "d")] + "TARGET_M6811 && (INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 0x0ff)" + [(set (match_dup 3) (match_dup 4)) + (set (match_dup 0) (match_dup 2)) + (set (match_dup 0) (plus:HI (zero_extend:HI (match_dup 3)) (match_dup 0)))] + "operands[4] = m68hc11_gen_lowpart (QImode, operands[1]);") + +;; +;; Replace: "ldx #N; xgdx; addd ; xgdx" by "ldab #N; ldx ; abx" +;; +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "const_int_operand" "")) + (set (match_dup 0) + (plus:HI (match_dup 0) + (match_operand:HI 2 "general_operand" "")))] + "TARGET_M6812" + [(set (match_dup 0) (match_dup 2)) + (set (match_dup 0) (plus:HI (match_dup 0) (match_dup 1)))] + "") + ;; ;; Optimize an address register increment and a compare to use ;; a PRE_INC or PRE_DEC addressing mode (disabled on the tst insn @@ -6579,11 +7097,11 @@ && reg_mentioned_p (operands[0], operands[2])" [(set (cc0) (match_dup 3))] "if (INTVAL (operands[1]) == 1) - operands[3] = gen_rtx (MEM, QImode, - gen_rtx (PRE_INC, HImode, operands[0])); + operands[3] = gen_rtx_MEM (QImode, + gen_rtx_PRE_INC (HImode, operands[0])); else - operands[3] = gen_rtx (MEM, QImode, - gen_rtx (PRE_DEC, HImode, operands[0])); + operands[3] = gen_rtx_MEM (QImode, + gen_rtx_PRE_DEC (HImode, operands[0])); ") ;; @@ -6601,11 +7119,11 @@ && reg_mentioned_p (operands[0], operands[3])" [(set (cc0) (compare (match_dup 2) (match_dup 4)))] "if (INTVAL (operands[1]) == 1) - operands[4] = gen_rtx (MEM, QImode, - gen_rtx (PRE_INC, HImode, operands[0])); + operands[4] = gen_rtx_MEM (QImode, + gen_rtx_PRE_INC (HImode, operands[0])); else - operands[4] = gen_rtx (MEM, QImode, - gen_rtx (PRE_DEC, HImode, operands[0])); + operands[4] = gen_rtx_MEM (QImode, + gen_rtx_PRE_DEC (HImode, operands[0])); ") (define_peephole2 @@ -6620,11 +7138,11 @@ && reg_mentioned_p (operands[0], operands[2])" [(set (cc0) (compare (match_dup 4) (match_dup 3)))] "if (INTVAL (operands[1]) == 1) - operands[4] = gen_rtx (MEM, QImode, - gen_rtx (PRE_INC, HImode, operands[0])); + operands[4] = gen_rtx_MEM (QImode, + gen_rtx_PRE_INC (HImode, operands[0])); else - operands[4] = gen_rtx (MEM, QImode, - gen_rtx (PRE_DEC, HImode, operands[0])); + operands[4] = gen_rtx_MEM (QImode, + gen_rtx_PRE_DEC (HImode, operands[0])); ") ;; @@ -6654,6 +7172,31 @@ (set (match_dup 0) (plus:HI (match_dup 0) (match_dup 1)))] "") +;; +;; +;; +(define_peephole2 + [(parallel + [(set (match_operand:SI 0 "hard_reg_operand" "") + (ashift:SI (match_operand:SI 1 "general_operand" "") + (const_int 1))) + (clobber (match_scratch:HI 2 ""))]) + (set (match_operand:HI 3 "nonimmediate_operand" "") (reg:HI D_REGNUM)) + (set (match_operand:HI 4 "nonimmediate_operand" "") (reg:HI X_REGNUM))] + "!X_REG_P (operands[1]) + && peep2_reg_dead_p (2, gen_rtx_REG (HImode, D_REGNUM)) + && peep2_reg_dead_p (3, gen_rtx_REG (HImode, X_REGNUM))" + [(set (reg:HI D_REGNUM) (match_dup 5)) + (set (reg:HI D_REGNUM) (ashift:HI (reg:HI D_REGNUM) (const_int 1))) + (set (match_dup 3) (reg:HI D_REGNUM)) + (set (reg:HI D_REGNUM) (match_dup 6)) + (parallel [(set (reg:HI D_REGNUM) + (rotate:HI (reg:HI D_REGNUM) (const_int 1))) + (clobber (reg:HI CC_REGNUM))]) + (set (match_dup 4) (reg:HI D_REGNUM))] + "operands[5] = m68hc11_gen_lowpart (HImode, operands[1]); + operands[6] = m68hc11_gen_highpart (HImode, operands[1]);") + ;; ;; Replace a "ldd ; psha; pshb" with a "ldx ; pshx". ;; @@ -6668,6 +7211,216 @@ (set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2))] "") +;; +;; Remove one load when copying a value to/from memory and also +;; to a register. Take care not clobbering a possible register used +;; by operand 2. +;; Replace: "ldd 0,y; std 2,y; ldx 0,y" into "ldx 0,y; stx 2,y" +;; +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "general_operand" "")) + (set (match_operand:HI 2 "nonimmediate_operand" "") (match_dup 0)) + (set (match_operand:HI 3 "hard_reg_operand" "") (match_dup 1))] + "peep2_reg_dead_p (2, operands[0]) + && !side_effects_p (operands[1]) + && !side_effects_p (operands[2]) + && !reg_mentioned_p (operands[3], operands[2])" + [(set (match_dup 3) (match_dup 1)) + (set (match_dup 2) (match_dup 3))] + "") + +;; +;; Replace a "ldd ; addd #N; std " into a +;; "ldx ; leax; stx " if we have a free X/Y register +;; and the constant is small. +;; +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "general_operand" "")) + (set (match_dup 0) (plus:HI (match_dup 0) + (match_operand:HI 2 "const_int_operand" ""))) + (set (match_operand:HI 3 "nonimmediate_operand" "") + (match_dup 0)) + (match_scratch:HI 4 "xy")] + "D_REG_P (operands[0]) + && (TARGET_M6812 + || (INTVAL (operands[2]) >= -2 && INTVAL (operands[2]) <= 2)) + && peep2_reg_dead_p (3, operands[0])" + [(set (match_dup 4) (match_dup 1)) + (set (match_dup 4) (plus:HI (match_dup 4) (match_dup 2))) + (set (match_dup 3) (match_dup 4))] + "if (reg_mentioned_p (operands[4], operands[1])) FAIL; + if (reg_mentioned_p (operands[4], operands[3])) FAIL;") + +;;-------------------------------------------------------------------- +;;- Bset peephole2 +;;-------------------------------------------------------------------- +;; These peepholes try to replace some logical sequences by 'bset' and 'bclr'. +;; +;; Replace 'ldab ; orab #N; stab ' by 'bset #N'. +;; Register D must be dead and there must be no register side effects for mem. +;; The *can* be volatile this is why we must not use 'side_effects_p'. +;; The good side effect is that it makes the sequence atomic. +;; +(define_peephole2 + [(set (match_operand:QI 0 "hard_reg_operand" "") + (match_operand:QI 1 "nonimmediate_operand" "")) + (set (match_dup 0) (ior:QI (match_dup 0) + (match_operand:QI 2 "const_int_operand" ""))) + (set (match_dup 1) (match_dup 0))] + "(TARGET_M6812 || m68hc11_indirect_p (operands[1], QImode)) + && (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0))) + && peep2_reg_dead_p (3, operands[0])" + [(set (match_dup 1) (ior:QI (match_dup 1) (match_dup 2)))] + "") + +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "nonimmediate_operand" "")) + (set (match_dup 0) (ior:HI (match_dup 0) + (match_operand:HI 2 "const_int_operand" ""))) + (set (match_dup 1) (match_dup 0))] + "(TARGET_M6812 || m68hc11_indirect_p (operands[1], HImode)) + && (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0))) + && peep2_reg_dead_p (3, operands[0])" + [(set (match_dup 1) (ior:HI (match_dup 1) (match_dup 2)))] + "") + +;;-------------------------------------------------------------------- +;;- Bclr peephole2 +;;-------------------------------------------------------------------- +;; Replace 'ldab ; andab #N; stab ' by 'bclr #N'. +;; See Bset peephole2. +;; +(define_peephole2 + [(set (match_operand:QI 0 "hard_reg_operand" "") + (match_operand:QI 1 "nonimmediate_operand" "")) + (set (match_dup 0) (and:QI (match_dup 0) + (match_operand:QI 2 "const_int_operand" ""))) + (set (match_dup 1) (match_dup 0))] + "(TARGET_M6812 || m68hc11_indirect_p (operands[1], QImode)) + && (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0))) + && peep2_reg_dead_p (3, operands[0])" + [(set (match_dup 1) (and:QI (match_dup 1) (match_dup 2)))] + "") + +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "nonimmediate_operand" "")) + (set (match_dup 0) (and:HI (match_dup 0) + (match_operand:HI 2 "const_int_operand" ""))) + (set (match_dup 1) (match_dup 0))] + "(TARGET_M6812 || m68hc11_indirect_p (operands[1], HImode)) + && (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0))) + && peep2_reg_dead_p (3, operands[0])" + [(set (match_dup 1) (and:HI (match_dup 1) (match_dup 2)))] + "") + + +;;-------------------------------------------------------------------- +;;- Compare peephole2 +;;-------------------------------------------------------------------- +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "hard_reg_operand" "")) + (set (match_dup 1) (plus:HI (match_dup 1) + (match_operand:HI 2 "const_int_operand" ""))) + (set (cc0) (match_dup 0))] + "peep2_reg_dead_p (3, operands[0]) && !Z_REG_P (operands[1])" + [(set (match_dup 1) (plus:HI (match_dup 1) (match_dup 2))) + (set (cc0) (compare (match_dup 1) (match_dup 2)))] + "") + +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "hard_reg_operand" "")) + (set (match_operand:HI 2 "hard_reg_operand" "") + (plus:HI (match_dup 2) + (match_operand:HI 3 "const_int_operand" ""))) + (set (match_operand:HI 4 "memory_operand" "") (match_dup 2)) + (set (cc0) (match_operand:HI 5 "hard_reg_operand" ""))] + "peep2_reg_dead_p (4, operands[5]) && !Z_REG_P (operands[2]) + && !reg_mentioned_p (operands[2], operands[4]) + + && ((rtx_equal_p (operands[5], operands[0]) + && rtx_equal_p (operands[2], operands[1])) + + || (rtx_equal_p (operands[5], operands[1]) + && rtx_equal_p (operands[2], operands[0])))" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 2) (plus:HI (match_dup 2) (match_dup 3))) + (set (match_dup 4) (match_dup 2)) + (set (cc0) (compare (match_dup 2) (match_dup 3)))] + "") + + +;;-------------------------------------------------------------------- +;;- Load peephole2 +;;-------------------------------------------------------------------- +;; +;; Optimize initialization of 2 hard regs from the same memory location +;; Since we can't copy easily X, Y and D to each other, load the 2 registers +;; from the same memory location. +;; +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "memory_operand" "")) + (set (match_operand:HI 2 "hard_reg_operand" "") (match_dup 0))] + "TARGET_M6811 + && !side_effects_p (operands[1]) + && !reg_mentioned_p (operands[0], operands[1])" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 1))] + "") + +;; Replace "ldd #N; addd " with "ldd ; addd #N". +;; +(define_peephole2 + [(set (match_operand:HI 0 "nonimmediate_operand" "") (const_int 0)) + (set (match_operand:HI 1 "nonimmediate_operand" "") (const_int 0)) + (set (match_operand:HI 2 "nonimmediate_operand" "") (const_int 0)) + (set (match_operand:HI 3 "nonimmediate_operand" "") (const_int 0)) + (match_scratch:HI 4 "d")] + "" + [(set (match_dup 4) (const_int 0)) + (set (match_dup 0) (match_dup 4)) + (set (match_dup 1) (match_dup 4)) + (set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 4))] + "") + +;; +;; Replace "ldd #N; addd " with "ldd ; addd #N". +;; +(define_peephole2 + [(set (match_operand:HI 0 "nonimmediate_operand" "") (const_int 0)) + (set (match_operand:HI 1 "nonimmediate_operand" "") (const_int 0)) + (set (match_operand:HI 2 "nonimmediate_operand" "") (const_int 0)) + (match_scratch:HI 3 "d")] + "" + [(set (match_dup 3) (const_int 0)) + (set (match_dup 0) (match_dup 3)) + (set (match_dup 1) (match_dup 3)) + (set (match_dup 2) (match_dup 3))] + "") + +;; +;; Replace "ldd #N; addd " with "ldd ; addd #N". +;; +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") (const_int 0)) + (set (match_operand:HI 1 "push_operand" "") (match_dup 0)) + (set (match_operand:HI 2 "push_operand" "") (match_dup 0)) + (set (match_operand:HI 3 "push_operand" "") (match_dup 0)) + (match_scratch:HI 4 "x")] + "TARGET_M6811 && D_REG_P (operands[0]) && peep2_reg_dead_p (4, operands[0])" + [(set (match_dup 4) (const_int 0)) + (set (match_dup 1) (match_dup 4)) + (set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 4))] + "") + ;; ;; This peephole catches the address computations generated by the reload ;; pass. @@ -6808,7 +7561,7 @@ rtx ops[2]; ops[0] = operands[0]; - ops[1] = gen_rtx (REG, HImode, HARD_D_REGNUM); + ops[1] = gen_rtx_REG (HImode, HARD_D_REGNUM); m68hc11_gen_movhi (insn, ops); return \"\"; } @@ -6816,7 +7569,7 @@ ;;; ;;; Catch an xgdx/xgdy followed by a (set D X/Y). If X/Y is dead, we don't -;;; need to emit anything. Otherwise, we just need an copy of D to X/Y. +;;; need to emit anything. Otherwise, we just need a copy of D to X/Y. ;;; (define_peephole [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A")) @@ -6832,7 +7585,7 @@ ;;; ;;; Catch an xgdx/xgdy followed by a (set D X/Y). If X/Y is dead, we don't -;;; need to emit anything. Otherwise, we just need an copy of D to X/Y. +;;; need to emit anything. Otherwise, we just need a copy of D to X/Y. ;;; (define_peephole [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A")) @@ -6861,7 +7614,7 @@ rtx ops[2]; ops[0] = operands[0]; - ops[1] = gen_rtx (REG, HImode, HARD_D_REGNUM); + ops[1] = gen_rtx_REG (HImode, HARD_D_REGNUM); m68hc11_gen_movhi (insn, ops); return \"\"; } @@ -6881,7 +7634,7 @@ rtx ops[2]; ops[0] = operands[0]; - ops[1] = gen_rtx (REG, HImode, HARD_D_REGNUM); + ops[1] = gen_rtx_REG (HImode, HARD_D_REGNUM); m68hc11_gen_movhi (insn, ops); return \"\"; } @@ -6918,8 +7671,8 @@ rtx ops[2]; ops[0] = operands[2]; - ops[1] = gen_rtx (MEM, HImode, - gen_rtx (POST_INC, HImode, stack_pointer_rtx)); + ops[1] = gen_rtx_MEM (HImode, + gen_rtx_POST_INC (HImode, stack_pointer_rtx)); m68hc11_gen_movhi (insn, ops); return \"\"; } @@ -6937,3 +7690,41 @@ return \"sts\\t%t0\\n\\tld%0\\t%t0\"; } ") + +(define_peephole + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "memory_operand" "")) + (set (match_operand:HI 2 "hard_reg_operand" "") (match_dup 0))] + "TARGET_M6811 + && !side_effects_p (operands[1]) + && !reg_mentioned_p (operands[0], operands[1])" + "* +{ + rtx ops[2]; + + ops[0] = operands[0]; + ops[1] = operands[1]; + m68hc11_gen_movhi (insn, ops); + ops[0] = operands[2]; + m68hc11_gen_movhi (insn, ops); + return \"\"; +}") + +;; Peephole for Z register replacement. +;; Avoid to use _.tmp register when comparing D and X if we can compare +;; with soft register +(define_peephole + [(set (match_operand:HI 0 "hard_reg_operand" "") (reg:HI SOFT_XY_REGNUM)) + (set (reg:HI SOFT_TMP_REGNUM) (match_dup 0)) + (set (cc0) (compare (match_operand:HI 2 "hard_reg_operand" "") + (reg:HI SOFT_TMP_REGNUM)))] + "X_REG_P (operands[0]) || Y_REG_P (operands[0])" + "* +{ + rtx ops[2]; + + ops[0] = operands[0]; + ops[1] = operands[1]; + m68hc11_gen_movhi (insn, ops); + return \"cp%2\\t%1\"; +}")