;;- Machine description file for Motorola 68HC11 and 68HC12.
-;;- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
-;;- Contributed by Stephane Carrez (stcarrez@worldnet.fr)
+;;- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+;;- 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)
;; 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
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;; 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
(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
])
;;--------------------------------------------------------------------
;;
;; Split pattern for (tst:QI) on an address register.
-;; The value is saved in memory and we test the low part only.
;;
(define_split
[(set (cc0)
- (match_operand:QI 0 "hard_addr_reg_operand" "xy"))]
+ (match_operand:QI 0 "hard_addr_reg_operand" ""))]
"z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode"
- [(set (match_dup 3) (match_dup 2))
- (set (cc0) (match_dup 4))]
- "operands[2] = gen_rtx (REG, HImode, REGNO (operands[0]));
- operands[3] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM);
- operands[4] = gen_rtx (REG, QImode, SOFT_TMP_REGNUM);")
+ [(parallel [(set (reg:HI D_REGNUM) (match_dup 1))
+ (set (match_dup 1) (reg:HI D_REGNUM))])
+ (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]));")
(define_insn "tstqi_1"
[(set (cc0)
(match_operand:QI 0 "tst_operand" "m,d,*A,!u"))]
""
- "@
- tst\\t%0
- tstb
- #
- tst\\t%b0")
+ "*
+{
+ if (A_REG_P (operands[0]))
+ return \"#\";
+
+ else if (D_REG_P (operands[0]))
+ return \"tstb\";
+
+ else if (dead_register_here (insn, d_reg))
+ return \"ldab\\t%b0\";
+
+ else
+ return \"tst\\t%b0\";
+}")
;;
;; tstqi_z_used, cmpqi_z_used and cmphi_z_used are patterns generated
;; 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" "m"))
- (use (match_operand:HI 1 "hard_reg_operand" "dxy"))
- (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);")
;;--------------------------------------------------------------------
;;
(define_split
[(set (cc0)
- (compare (match_operand:HI 0 "hard_reg_operand" "dxy")
- (match_operand:HI 1 "hard_reg_operand" "Aw")))]
- "reload_completed"
+ (compare (match_operand:HI 0 "hard_reg_operand" "")
+ (match_operand:HI 1 "hard_reg_operand" "")))]
+ "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" "")))]
+ "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)
DONE;
}")
-(define_insn "cmphi_1"
+(define_insn "cmphi_1_hc12"
[(set (cc0)
(compare (match_operand:HI 0 "tst_operand"
- "x,dy,xyd,?xy,d,m,!u,dxy,dxy")
- (match_operand:HI 1 "cmp_operand"
+ "d,?xy,xyd,?xy,d,m,!u,dxy,dxy")
+ (match_operand:HI 1 "general_operand"
"i,i,!u,m,m,dxy,dxy,?*d*A,!*w")))]
- ""
+ "TARGET_M6812"
"*
{
if (H_REG_P (operands[1]) && !H_REG_P (operands[0]))
return \"cp%0\\t%1\";
}")
-(define_insn "cmphi_z_used"
+(define_insn "cmphi_1_hc11"
[(set (cc0)
- (compare (match_operand:HI 0 "tst_operand" "dxy,m")
- (match_operand:HI 1 "cmp_operand" "m,dxy")))
- (use (match_operand:HI 2 "hard_reg_operand" "dxy,dxy"))
- (use (reg:HI 11))]
- ""
- "#")
-
-(define_split /* "cmphi_z_used" */
+ (compare (match_operand:HI 0 "tst_operand"
+ "dx,y,xyd,?xy,d,m,m,dxy,dxy,?u*z,dxy,*z")
+ (match_operand:HI 1 "cmp_operand"
+ "i,i,!u,m,m,?xy,d,?*d*A,?u,dxy,!*w,i")))]
+ "TARGET_M6811"
+ "*
+{
+ if (H_REG_P (operands[1]) && !H_REG_P (operands[0]))
+ {
+ cc_status.flags |= CC_REVERSED;
+ return \"cp%1\\t%0\";
+ }
+ else if (H_REG_P (operands[1]))
+ return \"#\";
+ else
+ return \"cp%0\\t%1\";
+}")
+
+(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))]
+ ""
+ "#"
"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.
;;
(define_split
[(set (cc0)
- (compare (match_operand:QI 0 "hard_addr_reg_operand" "xy")
- (match_operand:QI 1 "cmp_operand" "uimA")))]
+ (compare (match_operand:QI 0 "hard_addr_reg_operand" "")
+ (match_operand:QI 1 "cmp_operand" "")))]
"z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode"
[(parallel [(set (reg:HI D_REGNUM) (match_dup 3))
(set (match_dup 3) (reg:HI D_REGNUM))])
(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)
- (compare (match_operand:QI 0 "hard_reg_operand" "dxy")
- (match_operand:QI 1 "hard_reg_operand" "dxy")))]
+ (compare (match_operand:QI 0 "hard_reg_operand" "")
+ (match_operand:QI 1 "hard_reg_operand" "")))]
"reload_completed"
[(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)
(define_split /* "bitcmpqi" */
[(set (cc0)
- (and:QI (match_operand:QI 0 "tst_operand" "d")
- (match_operand:QI 1 "hard_addr_reg_operand" "xy")))]
- "z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode"
+ (and:QI (match_operand:QI 0 "tst_operand" "")
+ (match_operand:QI 1 "hard_addr_reg_operand" "")))]
+ "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" "d,m")
- (match_operand:QI 1 "cmp_operand" "m,d")))
- (use (match_operand:HI 2 "hard_reg_operand" "xy,xy"))
- (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)
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" "dxy,m")
- (match_operand:QI 1 "cmp_operand" "m,dxy")))
- (use (match_operand:HI 2 "hard_reg_operand" "dxy,dxy"))
- (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);")
-
-(define_expand "cmpdf"
- [(set (cc0)
- (compare (match_operand:DF 0 "general_operand" "")
- (match_operand:DF 1 "general_operand" "")))]
- "0"
- "
-{
- m68hc11_compare_op0 = operands[0];
- m68hc11_compare_op1 = operands[1];
- DONE;
-}")
-
-(define_expand "cmpsf"
- [(set (cc0)
- (compare (match_operand:SF 0 "general_operand" "")
- (match_operand:SF 1 "general_operand" "")))]
- "0"
- "
-{
- m68hc11_compare_op0 = operands[0];
- m68hc11_compare_op1 = operands[1];
- DONE;
-}")
+ "operands[3] = gen_rtx_REG (HImode, SOFT_Z_REGNUM);")
;;--------------------------------------------------------------------
;;- Move strict_low_part
;; (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" "+um,D,D"))
- (match_operand:SI 1 "general_operand" "D,Dim,u"))]
+ "#"
"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" "+um,dA,dA"))
- (match_operand:HI 1 "general_operand" "dA,dAim,u"))]
+ "#"
"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" "+mu,dA"))
- (match_operand:QI 1 "general_operand" "d,imudA"))]
+ "#"
"z_replacement_completed == 2"
[(set (match_dup 0) (match_dup 1))]
"")
;; 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
")
(define_insn "movdi_internal"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=U,!u,U,m,m,!u")
- (match_operand:DI 1 "general_operand" "iU,iU,!u,mi,!u,!mu"))
- (clobber (match_scratch:HI 2 "=&d,&d,&d,&d,&d,&d"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=ou,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" "=uUm")
- (match_operand:DI 1 "general_operand" "iuUm"))
- (clobber (match_scratch:HI 2 "=&d"))]
+ [(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]);
")
(define_insn "movdf_internal"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=U,!u,U,m,m,!u")
- (match_operand:DF 1 "general_operand" "iU,iU,!u,mi,!u,!mu"))
- (clobber (match_scratch:HI 2 "=&d,&d,&d,&d,&d,&d"))]
+ [(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"))]
""
"#")
(define_split
- [(set (match_operand:DF 0 "nonimmediate_operand" "=uUm")
- (match_operand:DF 1 "general_operand" "iuUm"))
- (clobber (match_scratch:HI 2 "=&d"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (match_operand:DF 1 "general_operand" ""))
+ (clobber (match_scratch:HI 2 ""))]
"reload_completed"
[(const_int 0)]
"m68hc11_split_move (operands[0], operands[1], operands[2]);
")
(define_insn "movsi_internal"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=mu,?D,m,?D,?u,?u,!u,D")
- (match_operand:SI 1 "general_operand" "imu,im,?D,!u,?D,mi,!u,!D"))
- (clobber (match_scratch:HI 2 "=&d,X,X,X,X,&d,&d,X"))]
+ [(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_split
- [(set (match_operand:SI 0 "nonimmediate_operand" "=m,D,m,D,!u,!u,!u,D")
- (match_operand:SI 1 "general_operand" "im,im,D,!u,D,mi,!u,!D"))
- (clobber (match_scratch:HI 2 "=&d,X,X,X,X,&d,&d,X"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
+ (match_operand:SI 1 "general_operand" ""))
+ (clobber (match_scratch:HI 2 ""))]
"reload_completed"
[(const_int 0)]
"m68hc11_split_move (operands[0], operands[1], operands[2]);
")
(define_insn "movsf_internal"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,D,m,D,!u,!u,!u,D")
- (match_operand:SF 1 "general_operand" "im,im,D,!u,D,mi,!u,!D"))
- (clobber (match_scratch:HI 2 "=&d,X,X,X,X,&d,&d,X"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=o!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" "=m,D,m,D,!u,!u,!u,D")
- (match_operand:SF 1 "general_operand" "im,im,D,!u,D,mi,!u,!D"))
- (clobber (match_scratch:HI 2 "=&d,X,X,X,X,&d,&d,X"))]
+ [(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]);
;;--------------------------------------------------------------------
(define_insn "*movhi2_push"
- [(set (match_operand:HI 0 "push_operand" "=<,<")
- (match_operand:HI 1 "general_operand" "xy,?d"))]
+ [(set (match_operand:HI 0 "push_operand" "=<,<,<")
+ (match_operand:HI 1 "general_operand" "xy,?d,!z"))]
"TARGET_M6811 && !TARGET_M6812"
"*
{
{
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));
;; appear in the source operand.
;;
(define_split
- [(set (match_operand:QI 0 "hard_addr_reg_operand" "=A")
+ [(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.
;;
(define_split
[(set (match_operand:QI 0 "nonimmediate_operand" "")
- (match_operand:QI 1 "hard_addr_reg_operand" "=A"))]
- "z_replacement_completed == 2 && GET_MODE (operands[1]) == QImode
+ (match_operand:QI 1 "hard_addr_reg_operand" ""))]
+ "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" "=<,<")
{
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));
(define_insn "*movqi_68hc12"
[(set (match_operand:QI 0 "nonimmediate_operand"
- "=d*AU*q,d*A*q,*u,d*A*q,m,m")
+ "=U,d*AU*q,d*A*qU,d*A*q,m,?*u,m")
(match_operand:QI 1 "general_operand"
- "*ri*q,U,*ri*qU,m,d*q,!A"))]
+ "U,*ri*q,U,m,d*q,*ri*qU,!*A"))]
"TARGET_M6812"
"*
{
}")
(define_insn "*movqi_m68hc11"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=dA*q,m,m,dA*q,*u")
- (match_operand:QI 1 "general_operand" "dAim*q,d*q,!A,*u,dA*q"))]
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=d*A*q,m,m,d*A*q,*u")
+ (match_operand:QI 1 "general_operand" "d*Aim*q,d*q,!*A,*u,d*A*q"))]
"TARGET_M6811"
"*
{
"#")
(define_split
- [(set (match_operand:DI 0 "push_operand" "=<")
- (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "dmu*B")))
+ [(set (match_operand:DI 0 "push_operand" "")
+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))
(clobber (match_scratch:HI 2 "=&dB"))]
"z_replacement_completed == 2"
[(const_int 0)]
/* 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]);
}
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));
}
}
{
/* 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]);
}")
(define_split
- [(set (match_operand:DI 0 "nonimmediate_operand" "=mu")
- (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "dmu*B")))
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))
(clobber (match_scratch:HI 2 "=&dB"))]
"z_replacement_completed == 2"
[(const_int 0)]
/* 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]);
"#")
(define_split
- [(set (match_operand:DI 0 "non_push_operand" "=m,m,m,!u,!u")
+ [(set (match_operand:DI 0 "non_push_operand" "")
(zero_extend:DI
- (match_operand:HI 1 "nonimmediate_operand" "m,dA,!u,dmA,!u")))
- (clobber (match_scratch:HI 2 "=&d,&dB,&dB,&dB,&dB"))]
+ (match_operand:HI 1 "nonimmediate_operand" "")))
+ (clobber (match_scratch:HI 2 ""))]
"z_replacement_completed == 2"
[(const_int 0)]
"
[(set (match_operand:DI 0 "nonimmediate_operand" "=m,m,!u,!u")
(zero_extend:DI
(match_operand:SI 1 "nonimmediate_operand" "m,Du,m,Du")))
- (clobber (match_scratch:HI 2 "=d,d,&dB,d"))]
+ (clobber (match_scratch:HI 2 "=d,d,d,d"))]
""
"#")
(define_split
- [(set (match_operand:DI 0 "nonimmediate_operand" "=m,m,!u,!u")
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
(zero_extend:DI
- (match_operand:SI 1 "nonimmediate_operand" "m,Du,m,Du")))
- (clobber (match_scratch:HI 2 "=d,d,&dB,d"))]
+ (match_operand:SI 1 "nonimmediate_operand" "")))
+ (clobber (match_scratch:HI 2 ""))]
"z_replacement_completed == 2"
[(const_int 0)]
"
"#")
(define_split
- [(set (match_operand:SI 0 "non_push_operand" "=D,mu,m,m,!u,!u")
+ [(set (match_operand:SI 0 "non_push_operand" "")
(zero_extend:SI
- (match_operand:HI 1 "nonimmediate_operand" "dAmu,dA,m,!u,m,!u")))
- (clobber (match_scratch:HI 2 "=X,X,&d,&dB,&dB,&dB"))]
+ (match_operand:HI 1 "nonimmediate_operand" "")))
+ (clobber (match_scratch:HI 2 ""))]
"reload_completed"
[(const_int 0)]
"
"#")
(define_split
- [(set (match_operand:SI 0 "non_push_operand" "=mu")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "dxy")))]
+ [(set (match_operand:SI 0 "non_push_operand" "")
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
"reload_completed && !X_REG_P (operands[0])"
[(set (match_dup 2) (zero_extend:HI (match_dup 1)))
(set (match_dup 3) (const_int 0))]
operands[3] = m68hc11_gen_highpart (HImode, operands[0]);")
(define_split
- [(set (match_operand:SI 0 "hard_reg_operand" "=D")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "dxymu")))]
+ [(set (match_operand:SI 0 "hard_reg_operand" "")
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
"z_replacement_completed == 2 && X_REG_P (operands[0])"
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (const_int 0))
"
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];
}
")
(define_insn "zero_extendqihi2"
- [(set (match_operand:HI 0 "non_push_operand" "=dm,d,*A,!u,d,m,!u")
+ [(set (match_operand:HI 0 "non_push_operand" "=dm,d,*A,!*u,d,m,!*u")
(zero_extend:HI
(match_operand:QI 1 "nonimmediate_operand" "d,*A,d*Am,d,!um,*A,*A")))]
""
""
"*
{
- extern rtx ix_reg;
rtx ops[3];
int need_tst = 0;
{
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);
}
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]))
{
{
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);
}
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
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]));
}
;; a temporary scratch memory location.
;;
(define_split
- [(set (match_operand:SI 0 "register_operand" "=D")
- (sign_extend:SI (match_operand:HI 1 "register_operand" "A")))]
+ [(set (match_operand:SI 0 "register_operand" "")
+ (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
"reload_completed && (Y_REG_P (operands[1]) || Z_REG_P (operands[1]))"
[(set (reg:HI D_REGNUM) (match_dup 1))
(set (match_dup 0) (sign_extend:SI (reg:HI D_REGNUM)))]
""
"*
{
- extern rtx ix_reg;
rtx ops[2];
int x_reg_used;
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);
}
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);
}
}
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);
}
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 \"\";
}")
[(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)).
[(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)).
[(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)). */
[(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)). */
;;
(define_expand "addsi3"
[(parallel [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (match_operand:SI 1 "register_operand" "")
+ (plus:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))
(clobber (match_scratch:HI 3 ""))])]
""
"")
-;;
-;; Translate D = D + D into D = D << 1
-;; We have to do this because adding a register to itself is not possible.
-;;
-;; Manipulation of A and B registers directly confuses the cse-regs pass
-;; so the split must be made after z-replacement register.
-;;
-(define_split
- [(set (match_operand:SI 0 "register_operand" "=D")
- (plus:SI (match_dup 0)
- (match_dup 0)))
- (clobber (match_scratch:HI 1 "=X"))]
- "reload_completed && z_replacement_completed == 2"
- [(set (reg:HI D_REGNUM) (ashift:HI (reg:HI D_REGNUM) (const_int 1)))
- (parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM))
- (set (reg:HI X_REGNUM) (reg:HI D_REGNUM))])
- (set (reg:QI B_REGNUM) (rotate:QI (reg:QI B_REGNUM) (reg:QI CC_REGNUM)))
- (set (reg:QI A_REGNUM) (rotate:QI (reg:QI A_REGNUM) (reg:QI CC_REGNUM)))
- (parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM))
- (set (reg:HI X_REGNUM) (reg:HI D_REGNUM))])]
- "")
-
-
(define_insn "*addsi3_zero_extendhi"
[(set (match_operand:SI 0 "register_operand" "=D,D,D,D")
(plus:SI (zero_extend:SI
}
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);
}
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 \"\";
}")
(define_split /* "*addsi3_zero_extendqi" */
- [(set (match_operand:SI 0 "register_operand" "=D,D")
+ [(set (match_operand:SI 0 "register_operand" "")
(plus:SI (zero_extend:SI
- (match_operand:QI 1 "general_operand" "dAmi,!dAmiu"))
- (match_operand:SI 2 "memory_operand" "m,m")))
+ (match_operand:QI 1 "general_operand" ""))
+ (match_operand:SI 2 "memory_operand" "")))
(clobber (match_scratch:HI 3 "=X,X"))]
"reload_completed"
[(set (reg:HI D_REGNUM) (zero_extend:HI (match_dup 1)))
{
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
{
ops[0] = operands[1];
}
- ops[1] = gen_rtx (CONST_INT, VOIDmode, 0);
+ ops[1] = const0_rtx;
}
else
{
}
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);
}
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;
}")
(define_insn "*addsi3"
- [(set (match_operand:SI 0 "non_push_operand" "=m,D,!u,?D,D")
+ [(set (match_operand:SI 0 "non_push_operand" "=o,D,!u,?D,D")
(plus:SI (match_operand:SI 1 "non_push_operand" "%0,0,0,0,0")
- (match_operand:SI 2 "general_operand" "ML,i,ML,?D,?miu")))
+ (match_operand:SI 2 "general_operand" "ML,i,ML,?D,?oiu")))
(clobber (match_scratch:HI 3 "=d,X,d,X,X"))]
""
"*
}
else
{
- ops[1] = gen_rtx (CONST_INT, VOIDmode, - val);
+ ops[1] = GEN_INT (- val);
add_insn = \"subd\\t%1\";
inc_insn = \"dex\";
incb_mem = \"dec\\t%b1\";
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 \"\";
}")
(define_split
- [(set (match_operand:SI 0 "register_operand" "=D,u")
- (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "const_int_operand" "")))
- (clobber (match_scratch:HI 3 "=X,d"))]
+ (clobber (match_scratch:HI 3 ""))]
"reload_completed && z_replacement_completed == 2
&& ((INTVAL (operands[2]) & 0x0FFFF) == 0)"
[(set (match_dup 5) (match_dup 6))
"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
{
")
(define_split
- [(set (match_operand:SI 0 "register_operand" "=D")
- (plus:SI (match_operand:SI 1 "register_operand" "%0")
- (match_operand:SI 2 "general_operand" "mui")))
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
(clobber (match_scratch:HI 3 "=X"))]
"reload_completed && z_replacement_completed == 2
&& (GET_CODE (operands[2]) != CONST_INT ||
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 \"\";
}")
{
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_split /* "*addhi3_strict_low_part" */
- [(set (strict_low_part (match_operand:QI 0 "register_operand" "+dxy"))
- (plus:QI (match_operand:QI 1 "register_operand" "")
- (match_operand:QI 2 "general_operand" "")))]
- "0 && z_replacement_completed == 2"
- [(set (match_dup 0)
- (plus:QI (match_dup 1) (match_dup 2)))]
- "")
-
-(define_split /* "*addhi3_strict_low_part" */
- [(set (match_operand:HI 0 "register_operand" "=dA")
- (plus:HI (match_operand:HI 1 "register_operand" "%0")
- (match_operand:HI 2 "general_operand" "")))
- (clobber (match_scratch:HI 3 ""))]
- "0 && z_replacement_completed == 2 && !SP_REG_P (operands[0])"
- [(set (match_dup 0)
- (plus:HI (match_dup 1) (match_dup 2)))]
- "")
-
(define_insn "*addhi3_68hc12"
- [(set (match_operand:HI 0 "register_operand" "=*d,A*w,A*w,A")
- (plus:HI (match_operand:HI 1 "register_operand" "%0,0,Aw,0")
- (match_operand:HI 2 "general_operand" "imA*wu,id,id,!muA")))]
+ [(set (match_operand:HI 0 "register_operand" "=xyd,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" "i,m*A*wu,id,id,!mu*A")))]
"TARGET_M6812"
"*
{
int val;
const char* insn_code;
- if (which_alternative >= 3)
+ if (which_alternative >= 4)
{
if (A_REG_P (operands[2]))
{
else
val = 1000;
- if (val != -1 || val != 1 || !rtx_equal_p (operands[0], operands[1]))
+ if ((val != -1 && val != 1) || !rtx_equal_p (operands[0], operands[1]))
{
m68hc11_notice_keep_cc (operands[0]);
switch (REGNO (operands[0]))
{
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);
+
if (GET_CODE (operands[2]) == CONST_INT
&& (val = INTVAL (operands[2])) != 0
&& (CONST_OK_FOR_LETTER_P (val, 'P')
|| (val > 0 && val <= 8)))
{
- 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);
while (val > 1 || val < -1)
{
if (val > 0)
return \"\";
}
- /* Need to transfer to SP to IY and then to D register.
- Register IY is lost, this is specified by the (clobber) statement. */
+ /* Need to transfer to SP to X/Y and then to D register.
+ Register X/Y is lost, this is specified by the (clobber) statement. */
output_asm_insn (\"ts%3\", operands);
- output_asm_insn (\"xgd%3\", operands);
- output_asm_insn (\"addd\\t%2\", operands);
- output_asm_insn (\"xgd%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)))
+ {
+ output_asm_insn (\"ldab\\t%2\", operands);
+ output_asm_insn (\"ab%3\", operands);
+ CC_STATUS_INIT;
+ }
+ else
+ {
+ output_asm_insn (\"xgd%3\", operands);
+ output_asm_insn (\"addd\\t%2\", operands);
+ output_asm_insn (\"xgd%3\", operands);
+ }
/* The status flags correspond to the addd. xgdy and tys do not
modify the flags. */
return \"t%3s\";
}")
-;;
-;; Translate d = d + d into d = d << 1
-;; We have to do this because adding a register to itself is not possible.
-;; ??? It's not clear whether this is really necessary.
-;;
-(define_split
- [(set (match_operand:HI 0 "hard_reg_operand" "=dA")
- (plus:HI (match_dup 0)
- (match_dup 0)))]
- "reload_completed"
- [(set (match_dup 0) (ashift:HI (match_dup 0) (const_int 1)))]
- "")
-
(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*A")
+ (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0,0,0")
+ (match_operand:HI 2 "general_operand" "N,I,i,I,mi*A*d,!u*d*w")))]
"TARGET_M6811"
"*
{
const char* insn_code;
int val;
- extern rtx ix_reg;
if (D_REG_P (operands[0]) && SP_REG_P (operands[2]))
{
;; ??? It's not clear whether this is really necessary.
;;
(define_split
- [(set (match_operand:QI 0 "hard_reg_operand" "=dA")
+ [(set (match_operand:QI 0 "hard_reg_operand" "")
(plus:QI (match_dup 0)
(match_dup 0)))]
"0 && reload_completed"
"")
(define_insn "*subsi3"
- [(set (match_operand:SI 0 "register_operand" "=D,D")
- (minus:SI (match_operand:SI 1 "general_operand" "0,!mui")
- (match_operand:SI 2 "general_operand" "!mui,!D")))
- (clobber (match_scratch:HI 3 "=X,X"))]
+ [(set (match_operand:SI 0 "register_operand" "=D,D,D,D,!u")
+ (minus:SI (match_operand:SI 1 "general_operand" "0,oi,0,!u,0")
+ (match_operand:SI 2 "general_operand" "oi,D,!u,D,!oui")))
+ (clobber (match_scratch:HI 3 "=X,X,X,X,d"))]
""
"#")
(define_insn "*subsi3_zero_extendhi"
[(set (match_operand:SI 0 "register_operand" "=D")
(minus:SI (match_operand:SI 1 "register_operand" "0")
- (zero_extend:SI (match_operand:HI 2 "general_operand" "d!mui"))))
+ (zero_extend:SI (match_operand:HI 2 "general_operand" "dmui*A"))))
(clobber (match_scratch:HI 3 "=X"))]
""
"*
{
rtx ops[2];
+ 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)));
+ else
+ 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)));
+ else
+ 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 \"\";
}")
(define_insn "*subsi3_zero_extendqi"
[(set (match_operand:SI 0 "register_operand" "=D")
(minus:SI (match_operand:SI 1 "register_operand" "0")
- (zero_extend:SI (match_operand:QI 2 "general_operand" "!dmui"))))
+ (zero_extend:SI (match_operand:QI 2 "general_operand" "dmui*A"))))
(clobber (match_scratch:HI 3 "=X"))]
""
"*
{
rtx ops[2];
+ if (A_REG_P (operands[2]))
+ {
+ 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);
+ }
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 \"\";
}")
;; reg:QI 7 -> ccr reg:QI 5 -> A
;;
(define_split /* "*subsi3" */
- [(set (match_operand:SI 0 "register_operand" "=D")
- (minus:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "general_operand" "mui")))
+ [(set (match_operand:SI 0 "register_operand" "")
+ (minus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
(clobber (match_scratch:HI 3 "=X"))]
"reload_completed && z_replacement_completed == 2
&& X_REG_P (operands[1])"
operands[4] = m68hc11_gen_lowpart (QImode, operands[4]);")
(define_split /* "*subsi3" */
- [(set (match_operand:SI 0 "register_operand" "=D")
- (minus:SI (match_operand:SI 1 "general_operand" "mui")
- (match_operand:SI 2 "register_operand" "D")))
+ [(set (match_operand:SI 0 "register_operand" "")
+ (minus:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "register_operand" "")))
(clobber (match_scratch:HI 3 "=X"))]
"reload_completed && z_replacement_completed == 2
&& X_REG_P (operands[2])"
operands[5] = m68hc11_gen_highpart (QImode, operands[4]);
operands[4] = m68hc11_gen_lowpart (QImode, operands[4]);")
+(define_split /* "*subsi3" */
+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
+ (minus:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
+ (clobber (match_scratch:HI 3 "=d"))]
+ "reload_completed && z_replacement_completed == 2
+ && !X_REG_P (operands[0])"
+ [(set (match_dup 3) (match_dup 4))
+ (set (match_dup 3) (minus:HI (match_dup 3) (match_dup 5)))
+ (set (match_dup 4) (match_dup 3))
+ (set (match_dup 3) (match_dup 6))
+ (set (reg:QI 6) (minus:QI (minus:QI (reg:QI 7) (reg:QI 6)) (match_dup 7)))
+ (set (reg:QI 5) (minus:QI (minus:QI (reg:QI 7) (reg:QI 5)) (match_dup 8)))
+ (set (match_dup 6) (match_dup 3))]
+ "operands[4] = m68hc11_gen_lowpart (HImode, operands[1]);
+ operands[5] = m68hc11_gen_lowpart (HImode, operands[2]);
+ operands[6] = m68hc11_gen_highpart (HImode, operands[1]);
+ operands[7] = m68hc11_gen_highpart (HImode, operands[2]);
+ operands[8] = m68hc11_gen_highpart (QImode, operands[7]);
+ operands[7] = m68hc11_gen_lowpart (QImode, operands[7]);")
+
;;
;; - 16-bit Subtract.
;;
(minus:HI (match_operand:HI 1 "register_operand" "0")
(match_operand:HI 2 "general_operand" "g")))]
""
- "
-{
- if (TARGET_M6811 && SP_REG_P (operands[0]))
- {
- emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
- gen_rtx (SET, VOIDmode,
- operand0,
- gen_rtx (MINUS, HImode,
- operand1, operand2)),
- gen_rtx (CLOBBER, VOIDmode,
- gen_rtx (SCRATCH, HImode, 0)))));
- DONE;
- }
-}")
+ "")
;;
;; Subtract from stack. This is better if we provide a pattern.
if (D_REG_P (operands[3]))
{
- output_asm_insn (\"xgdx\", operands);
+ int save_x;
+
+ save_x = !dead_register_here (insn, ix_reg);
+ if (save_x)
+ output_asm_insn (\"xgdx\", operands);
output_asm_insn (\"tsx\", operands);
output_asm_insn (\"xgdx\", operands);
output_asm_insn (\"subd\\t%2\", operands);
/* The status flags correspond to the addd. xgdx/y and tx/ys do not
modify the flags. */
output_asm_insn (\"txs\", operands);
- return \"xgdx\";
+ if (save_x)
+ return \"xgdx\";
+ else
+ return \"\";
}
/* Need to transfer to SP to X,Y and then to D register.
{
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\";
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);
}")
(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 "nonimmediate_operand" "%dum,0,0")
+ (match_operand:QI 2 "general_operand" "dium,*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);
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")
(mult:HI (sign_extend:HI
{
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);
}
;;- 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" "")
CC_STATUS_INIT;
/* The bclr instruction uses an inverted mask. */
- operands[1] = gen_rtx (CONST_INT, VOIDmode, (~val) & 0x0FFFF);
+ operands[1] = GEN_INT ((~val) & 0x0FFFF);
/* When destination is a global variable, generate a .relax instruction
and load the address in the clobber register. That load can be
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 \"\";
}
rtx ops[2];
ops[0] = operands[0];
- ops[1] = gen_rtx (CONST_INT, VOIDmode, (~val) & 0x0FF);
+ ops[1] = GEN_INT ((~val) & 0x0FF);
output_asm_insn (\"bclr\\t%b0, %1\", ops);
}
else if ((val & 0x0FF) != 0)
rtx ops[2];
ops[0] = operands[0];
- ops[1] = gen_rtx (CONST_INT, VOIDmode, ((~val) & 0x0FF00) >> 8);
+ ops[1] = GEN_INT (((~val) & 0x0FF00) >> 8);
output_asm_insn (\"bclr\\t%h0, %1\", ops);
}
else if ((val & 0x0FF00) != 0)
return \"#\";
CC_STATUS_INIT;
- return \"andb\\t%b2\\n\\tanda\\t%h2\";
+ return \"anda\\t%h2\\n\\tandb\\t%b2\";
}")
(define_expand "andqi3"
}
/* The bclr instruction uses an inverted mask. */
- operands[1] = gen_rtx (CONST_INT, VOIDmode, (~val) & 0x0FF);
+ operands[1] = GEN_INT ((~val) & 0x0FF);
/* When destination is a global variable, generate a .relax instruction
and load the address in the clobber register. That load can be
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 \"\";
}
rtx ops[2];
ops[0] = operands[0];
- ops[1] = gen_rtx (CONST_INT, VOIDmode, (~val) & 0x0FF);
+ ops[1] = GEN_INT ((~val) & 0x0FF);
output_asm_insn (\"bclr\\t%b0, %b1\", ops);
return \"\";
}
;;- 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" "")
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 \"\";
}
return \"#\";
CC_STATUS_INIT;
- return \"orab\\t%b2\\n\\toraa\\t%h2\";
+ return \"oraa\\t%h2\\n\\torab\\t%b2\";
}")
(define_expand "iorqi3"
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 \"\";
}
;;- 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")
}
CC_STATUS_INIT;
- return \"eorb\\t%b2\\n\\teora\\t%h2\";
+ return \"eora\\t%h2\\n\\teorb\\t%b2\";
}")
(define_insn "xorqi3"
;;- 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")]))]
""
- "#")
-
-(define_insn "*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))
- (set (reg:QI B_REGNUM) (match_op_dup 3 [(reg:QI B_REGNUM) (match_dup 5)]))
+ "#"
+ "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], QImode);
+ "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, QImode, HARD_A_REGNUM);
- operands[7] = gen_rtx (REG, QImode, HARD_D_REGNUM);
+ operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM);
operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM);
}
else
{
- operands[4] = m68hc11_gen_lowpart (HImode, operands[2]);
- operands[7] = operands[1];
- operands[5] = m68hc11_gen_lowpart (QImode, operands[4]);
- operands[4] = m68hc11_gen_highpart (QImode, operands[4]);
+ 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 24-bit part is cleared. */
+ /* For an AND, make sure the high 16-bit part is cleared. */
if (GET_CODE (operands[3]) == AND)
{
- operands[4] = const0_rtx;
operands[6] = const0_rtx;
}
")
-(define_split /* logicalsi3_zexthi */
- [(set (match_operand:SI 0 "register_operand" "")
+(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: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)]))
+ [(zero_extend:SI
+ (match_operand:QI 1 "general_operand" "d,*A,imu"))
+ (match_operand:SI 2 "general_operand" "imu,imu,0")]))]
+ ""
+ "#"
+ "z_replacement_completed == 2"
+ [(set (reg:QI A_REGNUM) (match_dup 4))
+ (set (reg:QI D_REGNUM) (match_dup 7))
+ (set (reg:QI B_REGNUM) (match_op_dup 3 [(reg:QI B_REGNUM) (match_dup 5)]))
(set (reg:HI X_REGNUM) (match_dup 6))]
- "PUT_MODE (operands[3], HImode);
+ "PUT_MODE (operands[3], QImode);
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);
+ 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
{
- operands[4] = operands[1];
- operands[5] = m68hc11_gen_lowpart (HImode, operands[2]);
+ operands[4] = m68hc11_gen_lowpart (HImode, operands[2]);
+ operands[7] = operands[1];
+ operands[5] = m68hc11_gen_lowpart (QImode, operands[4]);
+ operands[4] = m68hc11_gen_highpart (QImode, operands[4]);
operands[6] = m68hc11_gen_highpart (HImode, operands[2]);
}
- /* For an AND, make sure the high 16-bit part is cleared. */
+ /* For an AND, make sure the high 24-bit part is cleared. */
if (GET_CODE (operands[3]) == AND)
{
+ operands[4] = const0_rtx;
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))
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];
}
}
")
-(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)]))
"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
{
}
")
-(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
(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))]
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:
;;
;;
(define_split
- [(set (match_operand:HI 0 "hard_addr_reg_operand" "=A")
+ [(set (match_operand:HI 0 "hard_addr_reg_operand" "")
(match_operator:HI 3 "m68hc11_arith_operator"
- [(match_operand:HI 1 "hard_addr_reg_operand" "0")
- (match_operand:HI 2 "general_operand" "dAuim")]))]
+ [(match_operand:HI 1 "hard_addr_reg_operand" "")
+ (match_operand:HI 2 "general_operand" "")]))]
"z_replacement_completed == 2
/* If we are adding a small constant to X or Y, it's
better to use one or several inx/iny instructions. */
|| (GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) >= -4
&& INTVAL (operands[2]) <= 4)))"
- [(set (match_dup 4) (match_dup 5))
+ [(set (match_dup 9) (match_dup 0))
+ (set (match_dup 4) (match_dup 5))
(set (match_dup 8) (match_dup 7))
+ (set (match_dup 0) (match_dup 1))
(parallel [(set (reg:HI D_REGNUM) (match_dup 0))
(set (match_dup 0) (reg:HI D_REGNUM))])
(set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 6)]))
(parallel [(set (reg:HI D_REGNUM) (match_dup 0))
(set (match_dup 0) (reg:HI D_REGNUM))])]
"
+ operands[9] = operands[0];
+ /* For 68HC12, push the value on the stack and do the operation
+ with a pop. */
+ if (TARGET_M6812
+ && m68hc11_non_shift_operator (operands[3], HImode)
+ && (H_REG_P (operands[2])
+ || (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[5] = operands[2];
+ operands[8] = operands[7] = operands[0];
+ }
/* Save the operand2 in a temporary location and use it. */
- if ((H_REG_P (operands[2])
- || reg_mentioned_p (operands[0], operands[2]))
- && !(SP_REG_P (operands[2]) && GET_CODE (operands[3]) == PLUS))
+ else if ((H_REG_P (operands[2])
+ || reg_mentioned_p (operands[0], operands[2]))
+ && !(SP_REG_P (operands[2]) && GET_CODE (operands[3]) == PLUS))
{
- operands[4] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM);
+ 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[4] = operands[7] = operands[0];
+ operands[6] = operands[8];
+ operands[5] = operands[2];
+ }
+ else
+ {
+ operands[4] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM);
operands[6] = operands[4];
if (!H_REG_P (operands[2]))
{
operands[5] = operands[2];
operands[8] = operands[7] = operands[0];
}
+ }
}
else
{
")
(define_split
- [(set (match_operand:HI 0 "hard_addr_reg_operand" "=A")
+ [(set (match_operand:HI 0 "hard_addr_reg_operand" "")
(match_operator:HI 3 "m68hc11_arith_operator"
- [(match_operand:HI 1 "general_operand" "mu")
- (match_operand:HI 2 "general_operand" "dAuim")]))]
+ [(match_operand:HI 1 "general_operand" "")
+ (match_operand:HI 2 "general_operand" "")]))]
"z_replacement_completed == 2
/* If we are adding a small constant to X or Y, it's
better to use one or several inx/iny instructions. */
;; The shift operators are special and must not appear here.
;;
(define_split
- [(set (match_operand:HI 0 "d_register_operand" "=d")
+ [(set (match_operand:HI 0 "d_register_operand" "")
(match_operator:HI 3 "m68hc11_non_shift_operator"
- [(match_operand:HI 1 "d_register_operand" "%0")
- (match_operand:HI 2 "hard_reg_operand" "*d*A")]))]
- "z_replacement_completed == 2 && !SP_REG_P (operands[2])"
+ [(match_operand:HI 1 "d_register_operand" "")
+ (match_operand:HI 2 "hard_reg_operand" "")]))]
+ "TARGET_M6811
+ && 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
+;; logical/arithmetic operation with a pop.
+;;
+(define_split
+ [(set (match_operand:HI 0 "d_register_operand" "")
+ (match_operator:HI 3 "m68hc11_non_shift_operator"
+ [(match_operand:HI 1 "d_register_operand" "")
+ (match_operand:HI 2 "hard_reg_operand" "")]))]
+ "TARGET_M6812
+ && 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)));
+ ")
;;--------------------------------------------------------------------
;; 16-bit Unary operations on X and Y:
;;
;; NOT NEG
;;
-;; Operations on X or Y registers are split here. Instructions are
+;; Operations on X or Y registers are split here. Instructions are
;; changed into:
;; - xgdx/xgdy instruction pattern,
;; - The same operation on register D,
;; (set (REG:HI X) (PLUS:HI (REG:HI X) (REG:HI X)))
;;
(define_split
- [(set (match_operand:HI 0 "hard_addr_reg_operand" "=A")
+ [(set (match_operand:HI 0 "hard_addr_reg_operand" "")
(match_operator:HI 2 "m68hc11_unary_operator"
- [(match_operand 1 "general_operand" "uim*d*A")]))]
+ [(match_operand 1 "general_operand" "")]))]
"z_replacement_completed == 2"
[(set (match_dup 4) (match_dup 5))
(parallel [(set (reg:HI D_REGNUM) (match_dup 0))
|| 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
{
;; AND OR XOR PLUS MINUS ASHIFT ASHIFTRT LSHIFTRT ROTATE ROTATERT
;;
(define_split
- [(set (match_operand:QI 0 "hard_addr_reg_operand" "=xy")
+ [(set (match_operand:QI 0 "hard_addr_reg_operand" "")
(match_operator:QI 3 "m68hc11_arith_operator"
- [(match_operand:QI 1 "hard_addr_reg_operand" "%0")
- (match_operand:QI 2 "general_operand" "dxyuim")]))]
+ [(match_operand:QI 1 "hard_addr_reg_operand" "")
+ (match_operand:QI 2 "general_operand" "")]))]
"z_replacement_completed == 2
/* Reject a (plus:QI (reg:QI X) (const_int 1|-1)) because the
incqi pattern generates a better code. */
(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]
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];
}
")
;; The shift operators are special and must not appear here.
;;
(define_split
- [(set (match_operand:QI 0 "d_register_operand" "=d")
+ [(set (match_operand:QI 0 "d_register_operand" "")
(match_operator:QI 3 "m68hc11_non_shift_operator"
- [(match_operand:QI 1 "d_register_operand" "%0")
- (match_operand:QI 2 "hard_reg_operand" "*d*x*y")]))]
+ [(match_operand:QI 1 "d_register_operand" "")
+ (match_operand:QI 2 "hard_reg_operand" "")]))]
"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:
;;
;; NOT NEG
;;
-;; Operations on X or Y registers are split here. Instructions are
+;; Operations on X or Y registers are split here. Instructions are
;; changed into:
;; - xgdx/xgdy instruction pattern,
;; - The same operation on register D,
;; (set (REG:HI X) (PLUS:HI (REG:HI X) (REG:HI X)))
;;
(define_split
- [(set (match_operand:QI 0 "hard_addr_reg_operand" "=xy")
+ [(set (match_operand:QI 0 "hard_addr_reg_operand" "")
(match_operator:QI 2 "m68hc11_unary_operator"
- [(match_operand:QI 1 "general_operand" "uim*d*x*y")]))]
+ [(match_operand:QI 1 "general_operand" "")]))]
"z_replacement_completed == 2"
[(set (match_dup 4) (match_dup 5))
(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]));
if ((H_REG_P (operands[1])
&& !rtx_equal_p (operands[0], operands[1]))
|| reg_mentioned_p (operands[0], operands[1]))
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
{
(define_insn "negsi2"
[(set (match_operand:SI 0 "register_operand" "=D")
- (neg:SI (match_operand:SI 1 "register_operand" "0")))]
+ (neg:SI (match_operand:SI 1 "general_operand" "0")))]
""
"*
{
+ rtx ops[1];
+
CC_STATUS_INIT;
/* With -Os or without -O, use a special library call. */
if (optimize_size || optimize == 0)
return \"bsr\\t___negsi2\";
- /* 32-bit complement and add 1. The comb/coma set the carry and they
- are smaller (use it for low-part). The eorb/eora leave the carry
- unchanged but are bigger (use it for high-part). */
- output_asm_insn (\"comb\\n\\tcoma\\n\\taddd\\t#1\\n\\txgdx\", operands);
- output_asm_insn (\"eorb\\t#0xFF\\n\\teora\\t#0xFF\", operands);
- return \"adcb\\t#0\\n\\tadca\\t#0\\n\\txgdx\";
+ ops[0] = gen_label_rtx ();
+
+ /* 32-bit complement and add 1. */
+ output_asm_insn (\"comb\\n\\tcoma\\n\\txgdx\", operands);
+ output_asm_insn (\"comb\\n\\tcoma\\n\\tinx\\n\\txgdx\", operands);
+ output_asm_insn (\"bne\\t%l0\", ops);
+ output_asm_insn (\"inx\", operands);
+ (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0]));
+ return \"\";
}")
(define_insn "neghi2"
- [(set (match_operand:HI 0 "register_operand" "=d,d,*A")
+ [(set (match_operand:HI 0 "register_operand" "=d,d,x*y")
(neg:HI (match_operand:HI 1 "general_operand" "0,!duim,0")))]
""
"@
DONE;")
(define_insn "one_cmplsi2"
- [(set (match_operand:SI 0 "non_push_operand" "=D")
- (not:SI (match_operand:SI 1 "general_operand" "0")))]
+ [(set (match_operand:SI 0 "non_push_operand" "=D,m,!u")
+ (not:SI (match_operand:SI 1 "general_operand" "0,m,0")))
+ (clobber (match_scratch:HI 2 "=X,d,X"))]
""
- "bsr\\t___one_cmplsi2")
+ "@
+ bsr\\t___one_cmplsi2
+ #
+ #")
(define_insn "one_cmplhi2"
- [(set (match_operand:HI 0 "non_push_operand" "=d,m,!u,*A")
+ [(set (match_operand:HI 0 "non_push_operand" "=d,m,*A,u")
(not:HI (match_operand:HI 1 "general_operand" "0,0,0,0")))]
""
"@
comb\\n\\tcoma
com\\t%b0\\n\\tcom\\t%h0
- com\\t%b0\\n\\tcom\\t%h0
- #")
+ #
+ com\\t%b0\\n\\tcom\\t%h0")
(define_insn "one_cmplqi2"
- [(set (match_operand:QI 0 "non_push_operand" "=d,m,!u,!*A")
+ [(set (match_operand:QI 0 "non_push_operand" "=d,m,*A,u")
(not:QI (match_operand:QI 1 "general_operand" "0,0,0,0")))]
""
"@
comb
com\\t%b0
- com\\t%b0
- #")
+ #
+ com\\t%b0")
(define_split /* "*one_cmplsi2" */
- [(set (match_operand:SI 0 "non_push_operand" "=Dum")
- (not:SI (match_operand:SI 1 "non_push_operand" "0")))]
+ [(set (match_operand:SI 0 "non_push_operand" "")
+ (not:SI (match_dup 0)))
+ (clobber (match_scratch:HI 1 ""))]
"z_replacement_completed == 2
- && (!D_REG_P (operands[0]) || (optimize && optimize_size == 0))"
- [(set (reg:HI D_REGNUM) (not:HI (reg:HI D_REGNUM)))
- (parallel [(set (reg:HI X_REGNUM) (reg:HI D_REGNUM))
- (set (reg:HI D_REGNUM) (reg:HI X_REGNUM))])
- (set (reg:HI D_REGNUM) (not:HI (reg:HI D_REGNUM)))
- (parallel [(set (reg:HI X_REGNUM) (reg:HI D_REGNUM))
- (set (reg:HI D_REGNUM) (reg:HI X_REGNUM))])]
- "
-{
- /* The result pattern only works for D register.
- Generate 2 one_cmplhi2 instructions. */
- if (!D_REG_P (operands[0]))
- {
- rtx ops[2];
+ && (!X_REG_P (operands[0]) || (optimize && optimize_size == 0))"
+ [(set (match_dup 2) (not:HI (match_dup 2)))
+ (set (match_dup 3) (not:HI (match_dup 3)))]
+ "operands[2] = m68hc11_gen_lowpart (HImode, operands[0]);
+ operands[3] = m68hc11_gen_highpart (HImode, operands[0]);")
- ops[0] = m68hc11_gen_lowpart (HImode, operands[0]);
- ops[1] = m68hc11_gen_highpart (HImode, operands[0]);
- emit_insn (gen_one_cmplhi2 (ops[0], ops[0]));
- emit_insn (gen_one_cmplhi2 (ops[1], ops[1]));
- DONE;
- }
-}")
+(define_split /* "*one_cmplsi2" */
+ [(set (match_operand:SI 0 "non_push_operand" "")
+ (not:SI (match_operand:SI 1 "non_push_operand" "")))
+ (clobber (match_operand:HI 2 "d_register_operand" ""))]
+ "z_replacement_completed == 2
+ && (!X_REG_P (operands[0]) || (optimize && optimize_size == 0))"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 2) (not:HI (match_dup 2)))
+ (set (match_dup 4) (match_dup 2))
+ (set (match_dup 2) (match_dup 5))
+ (set (match_dup 2) (not:HI (match_dup 2)))
+ (set (match_dup 6) (match_dup 2))]
+ "operands[3] = m68hc11_gen_lowpart (HImode, operands[1]);
+ operands[5] = m68hc11_gen_highpart (HImode, operands[1]);
+ operands[4] = m68hc11_gen_lowpart (HImode, operands[0]);
+ operands[6] = m68hc11_gen_highpart (HImode, operands[0]);")
;;--------------------------------------------------------------------
;;- arithmetic shifts
}
}")
-(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" "=<,um")
- (ashift:DI (match_operand:DI 1 "general_operand" "umi,umi")
- (const_int 32)))
- (clobber (match_scratch:HI 2 "=&A,d"))]
+ "#"
"reload_completed"
[(const_int 0)]
"/* Move the lowpart in the highpart first in case the shift
{
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]),
}
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" "=um")
- (ashift:DI (match_operand:DI 1 "general_operand" "umi")
- (const_int 1)))
- (clobber (match_scratch:HI 2 "=d"))]
+ "#"
"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]);
operands[8] = m68hc11_gen_lowpart (HImode, operands[8]);")
(define_insn "addsi_silshr16"
- [(set (match_operand:SI 0 "register_operand" "=D")
- (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "uim")
+ [(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")))]
+ (match_operand:SI 2 "general_operand" "0,m!*u,0")))]
""
"#")
(define_split
- [(set (match_operand:SI 0 "register_operand" "=D")
- (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "uim")
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "")
(const_int 16))
- (match_operand:SI 2 "general_operand" "0")))]
- "z_replacement_completed == 2"
+ (match_operand:SI 2 "general_operand" "")))]
+ "z_replacement_completed == 2 && !X_REG_P (operands[1])"
[(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)))]
+ (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[1]);")
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "")
+ (const_int 16))
+ (match_operand:SI 2 "general_operand" "")))]
+ "z_replacement_completed == 2 && X_REG_P (operands[1])"
+ [(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]);
+ 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")
(plus:SI
"#")
(define_split
- [(set (match_operand:SI 0 "register_operand" "=D")
+ [(set (match_operand:SI 0 "register_operand" "")
(plus:SI
- (mult:SI (match_operand:SI 2 "general_operand" "uim")
+ (mult:SI (match_operand:SI 2 "general_operand" "")
(const_int 65536))
- (match_operand:SI 1 "general_operand" "0")))
+ (match_operand:SI 1 "general_operand" "")))
(clobber (match_scratch:HI 3 "=X"))]
"0 && reload_completed && z_replacement_completed == 2"
[(set (reg:HI X_REGNUM) (plus:HI (reg:HI X_REGNUM) (match_dup 4)))]
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" "=D")
- (plus:SI (and:SI (match_operand:SI 1 "general_operand" "%uim")
- (const_int 65535))
- (match_operand:SI 2 "general_operand" "0")))]
+ "#"
"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)))]
"")
(define_split
- [(set (match_operand:SI 0 "nonimmediate_operand" "=D,um")
- (ashift:SI (match_operand:SI 1 "general_operand" "Duim,D")
+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
+ (ashift:SI (match_operand:SI 1 "general_operand" "")
(const_int 16)))
- (clobber (match_scratch:HI 3 "=X,X"))]
+ (clobber (match_scratch:HI 3 ""))]
""
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (const_int 0))]
""
"#")
-(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" "=D")
- (ashift:SI (zero_extend:HI
- (match_operand:HI 1 "general_operand" "duim*a"))
- (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))]
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]))
{
/* 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);
if (!Y_REG_P (operands[2]))
{
rtx ops[1];
+ int y_dead = dead_register_here (insn, iy_reg);
ops[0] = operands[1];
- output_asm_insn (\"pshy\", operands);
- if (reg_mentioned_p (stack_pointer_rtx, operands[1]))
+ if (y_dead == 0)
{
- ops[0] = adjust_address (operands[1], GET_MODE (operands[1]), 2);
+ output_asm_insn (\"pshy\", operands);
+ if (reg_mentioned_p (stack_pointer_rtx, operands[1]))
+ ops[0] = adjust_address (operands[1], GET_MODE (operands[1]), 2);
}
output_asm_insn (\"ldy\\t%0\", ops);
output_asm_insn (\"bsr\\t___ashlsi3\", operands);
- return \"puly\";
+ return y_dead == 0 ? \"puly\" : \"\";
}
return \"bsr\\t___ashlsi3\";
}")
{
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;
}
}")
(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\";
}")
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);
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;
}
}")
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 \"\";
}
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;
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 \"\";
}
}")
(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 \"\";
}")
if (!Y_REG_P (operands[2]))
{
rtx ops[1];
+ int y_dead = dead_register_here (insn, iy_reg);
ops[0] = operands[1];
- output_asm_insn (\"pshy\", operands);
- if (reg_mentioned_p (stack_pointer_rtx, operands[1]))
+ if (y_dead == 0)
{
- ops[0] = adjust_address (operands[1], GET_MODE (operands[1]), 2);
+ output_asm_insn (\"pshy\", operands);
+ if (reg_mentioned_p (stack_pointer_rtx, operands[1]))
+ ops[0] = adjust_address (operands[1], GET_MODE (operands[1]), 2);
}
output_asm_insn (\"ldy\\t%0\", ops);
output_asm_insn (\"bsr\\t___ashrsi3\", operands);
- return \"puly\";
+ return y_dead == 0 ? \"puly\" : \"\";
}
return \"bsr\\t___ashrsi3\";
}")
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);
}
}")
-(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" "=<,um")
- (lshiftrt:DI (match_operand:DI 1 "general_operand" "umi,umi")
- (const_int 32)))
- (clobber (match_scratch:HI 2 "=&A,d"))]
+ "#"
"reload_completed"
[(const_int 0)]
"m68hc11_split_move (m68hc11_gen_lowpart (SImode, operands[0]),
"#")
(define_split
- [(set (match_operand:DI 0 "nonimmediate_operand" "=um")
- (lshiftrt:DI (match_operand:DI 1 "general_operand" "umi")
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (lshiftrt:DI (match_operand:DI 1 "general_operand" "")
(match_operand:DI 2 "const_int_operand" "")))
(clobber (match_scratch:HI 3 "=d"))]
"z_replacement_completed && INTVAL (operands[2]) >= 56"
(set (match_dup 5) (reg:HI D_REGNUM))
(set (match_dup 6) (reg:HI D_REGNUM))
(set (match_dup 7) (reg:HI D_REGNUM))]
- "operands[8] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 56);
+ "operands[8] = GEN_INT (INTVAL (operands[2]) - 56);
operands[4] = m68hc11_gen_lowpart (SImode, operands[0]);
operands[5] = m68hc11_gen_highpart (HImode, operands[4]);
operands[4] = m68hc11_gen_lowpart (HImode, operands[4]);
operands[6] = m68hc11_gen_lowpart (HImode, operands[6]);")
(define_split
- [(set (match_operand:DI 0 "nonimmediate_operand" "=um")
- (lshiftrt:DI (match_operand:DI 1 "general_operand" "umi")
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (lshiftrt:DI (match_operand:DI 1 "general_operand" "")
(match_operand:DI 2 "const_int_operand" "")))
(clobber (match_scratch:HI 3 "=d"))]
"z_replacement_completed && INTVAL (operands[2]) >= 48
(set (match_dup 5) (reg:HI D_REGNUM))
(set (match_dup 6) (reg:HI D_REGNUM))
(set (match_dup 7) (reg:HI D_REGNUM))]
- "operands[8] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 48);
+ "operands[8] = GEN_INT (INTVAL (operands[2]) - 48);
operands[4] = m68hc11_gen_lowpart (SImode, operands[0]);
operands[5] = m68hc11_gen_highpart (HImode, operands[4]);
operands[4] = m68hc11_gen_lowpart (HImode, operands[4]);
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" "=um")
- (lshiftrt:DI (match_operand:DI 1 "general_operand" "umi")
- (const_int 1)))
- (clobber (match_scratch:HI 2 "=d"))]
+ "#"
"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]);
"")
(define_split
- [(set (match_operand:SI 0 "non_push_operand" "=D,um")
- (lshiftrt:SI (match_operand:SI 1 "general_operand" "uim,D")
+ [(set (match_operand:SI 0 "non_push_operand" "")
+ (lshiftrt:SI (match_operand:SI 1 "general_operand" "")
(const_int 16)))
- (clobber (match_scratch:HI 3 "=X,X"))]
+ (clobber (match_scratch:HI 3 ""))]
"reload_completed && !(X_REG_P (operands[0]) && X_REG_P (operands[1]))"
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (const_int 0))]
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]))
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);
if (!Y_REG_P (operands[2]))
{
rtx ops[1];
+ int y_dead = dead_register_here (insn, iy_reg);
ops[0] = operands[1];
- output_asm_insn (\"pshy\", operands);
- if (reg_mentioned_p (stack_pointer_rtx, operands[1]))
+ if (y_dead == 0)
{
- ops[0] = adjust_address (operands[1], GET_MODE (operands[1]), 2);
+ output_asm_insn (\"pshy\", operands);
+ if (reg_mentioned_p (stack_pointer_rtx, operands[1]))
+ ops[0] = adjust_address (operands[1], GET_MODE (operands[1]), 2);
}
output_asm_insn (\"ldy\\t%0\", ops);
output_asm_insn (\"bsr\\t___lshrsi3\", operands);
- return \"puly\";
+ return y_dead == 0 ? \"puly\" : \"\";
}
return \"bsr\\t___lshrsi3\";
}")
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;
}
}")
}")
(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"
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);
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 \"\";
}")
(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))]
""
"*
{
(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))]
""
"*
{
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")))]
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_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"
+(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")))]
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
;;--------------------------------------------------------------------
smaller and a little bit faster. This happens quite often due
to reloading of operands[0]. In that case, flags are set correctly
due to the load instruction. */
- if (cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+ if ((cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+ || (cc_status.value2 && rtx_equal_p (cc_status.value2, operands[0])))
return \"beq\\t%l1\";
else
return \"tbeq\\t%0,%l1\";
"TARGET_M6812"
"*
{
- if (cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+ if ((cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+ || (cc_status.value2 && rtx_equal_p (cc_status.value2, operands[0])))
return \"bne\\t%l1\";
else
return \"tbne\\t%0,%l1\";
"TARGET_M6812"
"*
{
- if (cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+ if ((cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+ || (cc_status.value2 && rtx_equal_p (cc_status.value2, operands[0])))
return \"beq\\t%l1\";
else
return \"tbeq\\tb,%l1\";
"TARGET_M6812"
"*
{
- if (cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+ if ((cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+ || (cc_status.value2 && rtx_equal_p (cc_status.value2, operands[0])))
return \"bne\\t%l1\";
else
return \"tbne\\tb,%l1\";
{
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\";
{
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\";
if (ret_size && ret_size <= 2)
{
- emit_insn (gen_rtx (PARALLEL, VOIDmode,
- gen_rtvec (2, gen_rtx_RETURN (VOIDmode),
- gen_rtx_USE (VOIDmode,
- gen_rtx_REG (HImode, 1)))));
+ emit_jump_insn (gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec (2, gen_rtx_RETURN (VOIDmode),
+ gen_rtx_USE (VOIDmode,
+ gen_rtx_REG (HImode, 1)))));
DONE;
}
if (ret_size)
{
- emit_insn (gen_rtx (PARALLEL, VOIDmode,
- gen_rtvec (2, gen_rtx_RETURN (VOIDmode),
- gen_rtx_USE (VOIDmode,
- gen_rtx_REG (SImode, 0)))));
+ emit_jump_insn (gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec (2, gen_rtx_RETURN (VOIDmode),
+ gen_rtx_USE (VOIDmode,
+ gen_rtx_REG (SImode, 0)))));
DONE;
}
}")
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 (current_function_return_rtx)
+ ret_size = GET_MODE_SIZE (GET_MODE (current_function_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"
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"
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"
;;- 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.
+;;
+(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,
+ gen_rtx_REG (HImode, HARD_SP_REGNUM)));")
+
+;;
+;; Optimize memory<->memory moves when the value is also loaded in
+;; a register.
+;;
+(define_peephole2
+ [(set (match_operand:QI 0 "memory_operand" "")
+ (match_operand:QI 1 "memory_operand" ""))
+ (set (reg:QI D_REGNUM)
+ (match_operand:QI 2 "memory_operand" ""))]
+ "(rtx_equal_p (operands[0], operands[2]) && !side_effects_p (operands[0]))
+ || (GET_CODE (XEXP (operands[0], 0)) == REG
+ && GET_CODE (XEXP (operands[2], 0)) == POST_INC
+ && rtx_equal_p (XEXP (operands[0], 0), XEXP (XEXP (operands[2], 0), 0)))"
+ [(set (reg:QI D_REGNUM) (match_dup 1))
+ (set (match_dup 2) (reg:QI D_REGNUM))]
+ "")
+
+;;
+;; Remove a possible move before a compare instruction when that
+;; move will go in a dead register. Compare with the source then.
+;;
+(define_peephole2
+ [(set (match_operand:HI 0 "hard_reg_operand" "")
+ (match_operand:HI 1 "hard_reg_operand" ""))
+ (set (cc0)
+ (compare (match_dup 0)
+ (match_operand:HI 2 "cmp_operand" "")))]
+ "(X_REG_P (operands[1]) || Y_REG_P (operands[1]))
+ && peep2_reg_dead_p (2, operands[0])
+ && !reg_mentioned_p (operands[0], operands[2])"
+ [(set (cc0) (compare (match_dup 1) (match_dup 2)))]
+ "")
+
+;;
+;; Optimize loading a constant to memory when that same constant
+;; is loaded to a hard register. Switch the two to use the register
+;; for memory initialization. In most cases, the constant is 0.
+;;
+(define_peephole2
+ [(set (match_operand:HI 0 "memory_operand" "")
+ (match_operand:HI 1 "immediate_operand" ""))
+ (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])"
+ [(set (match_dup 2) (match_dup 1))
+ (set (match_dup 0) (match_dup 2))]
+ "")
+
;;
;; Reorganize to optimize address computations.
;;
"")
;;
-;; Reorganize address computation based on stack pointer.
+;; Optimize an address register increment and a compare to use
+;; a PRE_INC or PRE_DEC addressing mode (disabled on the tst insn
+;; before reload, but can be enabled after).
+;;
+(define_peephole2
+ [(set (match_operand:HI 0 "hard_reg_operand" "")
+ (plus:HI (match_dup 0)
+ (match_operand:HI 1 "const_int_operand" "")))
+ (set (cc0)
+ (match_operand:QI 2 "memory_operand" ""))]
+ "TARGET_AUTO_INC_DEC
+ && (INTVAL (operands[1]) == -1 || INTVAL (operands[1]) == 1)
+ && 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]));
+ else
+ operands[3] = gen_rtx_MEM (QImode,
+ gen_rtx_PRE_DEC (HImode, operands[0]));
+ ")
+
+;;
+;; Likewise for compare.
+;;
+(define_peephole2
+ [(set (match_operand:HI 0 "hard_reg_operand" "")
+ (plus:HI (match_dup 0)
+ (match_operand:HI 1 "const_int_operand" "")))
+ (set (cc0)
+ (compare (match_operand:QI 2 "hard_reg_operand" "")
+ (match_operand:QI 3 "memory_operand" "")))]
+ "TARGET_AUTO_INC_DEC
+ && (INTVAL (operands[1]) == -1 || INTVAL (operands[1]) == 1)
+ && 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]));
+ else
+ operands[4] = gen_rtx_MEM (QImode,
+ gen_rtx_PRE_DEC (HImode, operands[0]));
+ ")
+
+(define_peephole2
+ [(set (match_operand:HI 0 "hard_reg_operand" "")
+ (plus:HI (match_dup 0)
+ (match_operand:HI 1 "const_int_operand" "")))
+ (set (cc0)
+ (compare (match_operand:QI 2 "memory_operand" "")
+ (match_operand:QI 3 "hard_reg_operand" "")))]
+ "TARGET_AUTO_INC_DEC
+ && (INTVAL (operands[1]) == -1 || INTVAL (operands[1]) == 1)
+ && 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]));
+ else
+ operands[4] = gen_rtx_MEM (QImode,
+ gen_rtx_PRE_DEC (HImode, operands[0]));
+ ")
+
+;;
+;; Replace a "ldx #N; addx <sp>" with a "ldx <sp>; addx #n"
+;; (avoids many temporary moves because we can't add sp to another reg easily)
;;
(define_peephole2
[(set (match_operand:HI 0 "hard_reg_operand" "")
"")
;;
+;; Replace "ldd #N; addd <op>" with "ldd <op>; addd #N".
+;;
+(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" "")))]
+ "(INTVAL (operands[1]) >= -2 && INTVAL (operands[1]) <= 2)"
+ [(set (match_dup 0) (match_dup 2))
+ (set (match_dup 0) (plus:HI (match_dup 0) (match_dup 1)))]
+ "")
+
+;;
+;; Replace a "ldd <mem>; psha; pshb" with a "ldx <mem>; pshx".
+;;
+(define_peephole2
+ [(set (match_operand:HI 0 "hard_reg_operand" "")
+ (match_operand:HI 1 "memory_operand" ""))
+ (set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM)))
+ (match_dup 0))
+ (match_scratch:HI 2 "x")]
+ "TARGET_M6811 && D_REG_P (operands[0]) && peep2_reg_dead_p (2, operands[0])"
+ [(set (match_dup 2) (match_dup 1))
+ (set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2))]
+ "")
+
+;;
+;; Replace a "ldd <mem>; addd #N; std <mem>" into a
+;; "ldx <mem>; leax; stx <mem>" 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;")
+
+;;
;; This peephole catches the address computations generated by the reload
;; pass.
(define_peephole
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 \"\";
}
;;;
;;; 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"))
;;;
;;; 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"))
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 \"\";
}
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 \"\";
}
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 \"\";
}