From 9ffd661f11e88f45057b1b54fa8996086da8be8f Mon Sep 17 00:00:00 2001
From: ciceron <ciceron@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Sun, 2 Mar 2003 20:04:27 +0000
Subject: [PATCH] 	* config/m68hc11/m68hc11.c (m68hc11_shift_operator):
 New function. 	* config/m68hc11/m68hc11-protos.h (m68hc11_shift_operator):
 Declare. 	* config/m68hc11/m68hc11.h (PREDICATE_CODES): Register. 
 * config/m68hc11/m68hc11.md ("rotrhi3", "rotlhi3"): New patterns for 
 rotatert and rotate. 	("rotrhi3_const", "rotlhi3_const"): Rename of old
 'rotrhi3' insns. 	("*rotrhi3", "*rotlhi3"): New insn pattern for
 non-const rotatert. 	("*rotrhi3_addr"): New split for shift insns on
 address register. 	("*lshrhi3", "*ashrhi3", "*ashlhi3_2"): Use new split.
 	* config/m68hc11/larith.asm (___rotlhi3): New asm function. 
 (___rotrhi3): Likewise. 	* config/m68hc11/t-m68hc11-gas (LIB1ASMFUNCS):
 Build them.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@63677 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                       |  15 +++
 gcc/config/m68hc11/larith.asm       |  43 ++++++++-
 gcc/config/m68hc11/m68hc11-protos.h |   3 +-
 gcc/config/m68hc11/m68hc11.c        |  10 ++
 gcc/config/m68hc11/m68hc11.h        |   1 +
 gcc/config/m68hc11/m68hc11.md       | 140 ++++++++++++++++++++++------
 gcc/config/m68hc11/t-m68hc11-gas    |   2 +-
 7 files changed, 184 insertions(+), 30 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7f92216e79e7..03eb0fac32ee 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2003-03-02  Stephane Carrez  <stcarrez@nerim.fr>
+
+	* config/m68hc11/m68hc11.c (m68hc11_shift_operator): New function.
+	* config/m68hc11/m68hc11-protos.h (m68hc11_shift_operator): Declare.
+	* config/m68hc11/m68hc11.h (PREDICATE_CODES): Register.
+	* config/m68hc11/m68hc11.md ("rotrhi3", "rotlhi3"): New patterns for 
+	rotatert and rotate.
+	("rotrhi3_const", "rotlhi3_const"): Rename of old 'rotrhi3' insns.
+	("*rotrhi3", "*rotlhi3"): New insn pattern for non-const rotatert.
+	("*rotrhi3_addr"): New split for shift insns on address register.
+	("*lshrhi3", "*ashrhi3", "*ashlhi3_2"): Use new split.
+	* config/m68hc11/larith.asm (___rotlhi3): New asm function.
+	(___rotrhi3): Likewise.
+	* config/m68hc11/t-m68hc11-gas (LIB1ASMFUNCS): Build them.
+
 2003-03-02  Neil Booth  <neil@daikokuya.co.uk>
 
 	* toplev.c (aux_base_name): Moved from toplev.h.
diff --git a/gcc/config/m68hc11/larith.asm b/gcc/config/m68hc11/larith.asm
index 80b881747370..0acf91228597 100644
--- a/gcc/config/m68hc11/larith.asm
+++ b/gcc/config/m68hc11/larith.asm
@@ -1,5 +1,5 @@
 /* libgcc routines for M68HC11 & M68HC12.
-   Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -578,6 +578,47 @@ Return_zero:
 	rts
 #endif
 
+#ifdef L_rotrhi3
+	.sect .text
+	.globl ___rotrhi3
+
+___rotrhi3:
+	xgdx
+	clra
+	andb	#0x0f
+	xgdx
+	beq	Return
+Loop:
+	tap
+	rorb
+	rora
+	dex
+	bne	Loop
+Return:
+	rts
+#endif
+
+#ifdef L_rotlhi3
+	.sect .text
+	.globl ___rotlhi3
+
+___rotlhi3:
+	xgdx
+	clra
+	andb	#0x0f
+	xgdx
+	beq	Return
+Loop:
+	asrb
+	rolb
+	rola
+	rolb
+	dex
+	bne	Loop
+Return:
+	rts
+#endif
+
 #ifdef L_ashrhi3
 	.sect .text
 	.globl ___ashrhi3
diff --git a/gcc/config/m68hc11/m68hc11-protos.h b/gcc/config/m68hc11/m68hc11-protos.h
index ec43ca0ac156..5bb69cf98517 100644
--- a/gcc/config/m68hc11/m68hc11-protos.h
+++ b/gcc/config/m68hc11/m68hc11-protos.h
@@ -1,5 +1,5 @@
 /* Prototypes for exported functions defined in m68hc11.c
-   Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
    Contributed by Stephane Carrez (stcarrez@nerim.fr)
 
 This file is part of GNU CC.
@@ -117,6 +117,7 @@ extern int arith_src_operand PARAMS((rtx, enum machine_mode));
 extern int m68hc11_logical_operator PARAMS((rtx, enum machine_mode));
 extern int m68hc11_arith_operator PARAMS((rtx, enum machine_mode));
 extern int m68hc11_non_shift_operator PARAMS((rtx, enum machine_mode));
+extern int m68hc11_shift_operator PARAMS((rtx, enum machine_mode));
 extern int m68hc11_unary_operator PARAMS((rtx, enum machine_mode));
 extern int non_push_operand PARAMS((rtx, enum machine_mode));
 extern int hard_reg_operand PARAMS((rtx, enum machine_mode));
diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c
index 6dafb1988185..e99b844edea2 100644
--- a/gcc/config/m68hc11/m68hc11.c
+++ b/gcc/config/m68hc11/m68hc11.c
@@ -1140,6 +1140,16 @@ m68hc11_non_shift_operator (op, mode)
     || GET_CODE (op) == PLUS || GET_CODE (op) == MINUS;
 }
 
+/* Return true if op is a shift operator.  */
+int
+m68hc11_shift_operator (op, mode)
+     register rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  return GET_CODE (op) == ROTATE || GET_CODE (op) == ROTATERT
+    || GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ASHIFT
+    || GET_CODE (op) == ASHIFTRT;
+}
 
 int
 m68hc11_unary_operator (op, mode)
diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h
index c51f19242549..df4f8184e0c7 100644
--- a/gcc/config/m68hc11/m68hc11.h
+++ b/gcc/config/m68hc11/m68hc11.h
@@ -1643,6 +1643,7 @@ do {                                                                    \
 			      ROTATE, ROTATERT }},			\
 {"m68hc11_non_shift_operator", {AND, IOR, XOR, PLUS, MINUS}},		\
 {"m68hc11_unary_operator",   {NEG, NOT, SIGN_EXTEND, ZERO_EXTEND}},	\
+{"m68hc11_shift_operator",   {ASHIFT, ASHIFTRT, LSHIFTRT, ROTATE, ROTATERT}},\
 {"non_push_operand",         {SUBREG, REG, MEM}},			\
 {"reg_or_some_mem_operand",  {SUBREG, REG, MEM}},			\
 {"tst_operand",              {SUBREG, REG, MEM}},			\
diff --git a/gcc/config/m68hc11/m68hc11.md b/gcc/config/m68hc11/m68hc11.md
index 92676c6af1de..8117d4869739 100644
--- a/gcc/config/m68hc11/m68hc11.md
+++ b/gcc/config/m68hc11/m68hc11.md
@@ -4757,13 +4757,16 @@
 
 
 (define_insn "*ashlhi3_2"
-  [(set (match_operand:HI 0 "register_operand" "=d")
-	(ashift:HI (match_operand:HI 1 "register_operand" "0")
-                   (match_operand:HI 2 "register_operand" "+x")))
+  [(set (match_operand:HI 0 "register_operand" "=d,*x")
+	(ashift:HI (match_operand:HI 1 "register_operand" "0,0")
+                   (match_operand:HI 2 "register_operand" "+x,+d")))
    (clobber (match_dup 2))]
   ""
   "*
 {
+  if (A_REG_P (operands[0]))
+    return \"#\";
+
   CC_STATUS_INIT;
   return \"bsr\\t___lshlhi3\";
 }")
@@ -5046,21 +5049,17 @@
 }")
 
 (define_insn "*ashrhi3"
-  [(set (match_operand:HI 0 "register_operand" "=d,x")
+  [(set (match_operand:HI 0 "register_operand" "=d,*x")
 	(ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0")
 	             (match_operand:HI 2 "register_operand" "+x,+d")))
    (clobber (match_dup 2))]
   ""
   "*
 {
-  CC_STATUS_INIT;
-  if (D_REG_P (operands[2]))
-    output_asm_insn (\"xgd%0\", operands);
+  if (A_REG_P (operands[0]))
+    return \"#\";
 
   output_asm_insn (\"bsr\\t___ashrhi3\", operands);
-  if (D_REG_P (operands[2]))
-    output_asm_insn (\"xgd%0\", operands);
-
   return \"\"; 
 }")
 
@@ -5594,22 +5593,17 @@
 }")
 
 (define_insn "*lshrhi3"
-  [(set (match_operand:HI 0 "register_operand" "=d,x")
+  [(set (match_operand:HI 0 "register_operand" "=d,*x")
 	(lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0")
 		     (match_operand:HI 2 "register_operand" "+x,+d")))
    (clobber (match_dup 2))]
   ""
   "*
 {
-  CC_STATUS_INIT;
-  if (D_REG_P (operands[2]))
-    output_asm_insn (\"xgd%0\", operands);
-
-  output_asm_insn (\"bsr\\t___lshrhi3\", operands);
-  if (D_REG_P (operands[2]))
-    output_asm_insn (\"xgd%0\", operands);
+  if (A_REG_P (operands[0]))
+    return \"#\";
 
-  return \"\"; 
+  return \"bsr\\t___lshrhi3\";
 }")
 
 (define_expand "lshrqi3"
@@ -5780,7 +5774,41 @@
   return \"\";
 }")
 
-(define_insn "rotlhi3"
+(define_insn "rotrqi3"
+  [(set (match_operand:QI 0 "register_operand" "=d,!q")
+	(rotatert:QI (match_operand:QI 1 "register_operand" "0,0")
+		     (match_operand:QI 2 "const_int_operand" "i,i")))]
+  ""
+  "*
+{
+  m68hc11_gen_rotate (ROTATERT, insn, operands);
+  return \"\";
+}")
+
+(define_expand "rotlhi3"
+  [(set (match_operand:HI 0 "register_operand" "")
+	(rotate:HI (match_operand:HI 1 "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_ROTATE (HImode,
+						operand1, scratch)),
+			      gen_rtx (CLOBBER, VOIDmode, scratch))));
+      DONE;
+    }
+}")
+
+(define_insn "rotlhi3_const"
   [(set (match_operand:HI 0 "register_operand" "=d")
 	(rotate:HI (match_operand:HI 1 "register_operand" "0")
 		   (match_operand:HI 2 "const_int_operand" "i")))]
@@ -5791,18 +5819,44 @@
   return \"\";
 }")
 
-(define_insn "rotrqi3"
-  [(set (match_operand:QI 0 "register_operand" "=d,!q")
-	(rotatert:QI (match_operand:QI 1 "register_operand" "0,0")
-		     (match_operand:QI 2 "const_int_operand" "i,i")))]
+(define_insn "*rotlhi3"
+  [(set (match_operand:HI 0 "register_operand" "=d,*x")
+	(rotate:HI (match_operand:HI 1 "register_operand" "0,0")
+		   (match_operand:HI 2 "general_operand" "+x,+d")))
+   (clobber (match_dup 2))]
   ""
   "*
 {
-  m68hc11_gen_rotate (ROTATERT, insn, operands);
-  return \"\";
+  if (A_REG_P (operands[0]))
+    return \"#\";
+
+  return \"bsr\\t___rotlhi3\";
+}")
+
+(define_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")))]
@@ -5813,6 +5867,38 @@
   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))])]
+  "")
+
 ;;--------------------------------------------------------------------
 ;;-  Jumps and transfers
 ;;--------------------------------------------------------------------
diff --git a/gcc/config/m68hc11/t-m68hc11-gas b/gcc/config/m68hc11/t-m68hc11-gas
index 1833fd56dc33..b5404cc84797 100644
--- a/gcc/config/m68hc11/t-m68hc11-gas
+++ b/gcc/config/m68hc11/t-m68hc11-gas
@@ -23,7 +23,7 @@ LIB1ASMFUNCS = _mulsi3 \
 	_regs_min _regs_frame _regs_d1_2 \
 	_regs_d3_4 _regs_d5_6 _regs_d7_8 _regs_d9_16 _regs_d17_32 \
 	_premain __exit _abort _cleanup \
-	_adddi3 _subdi3 _notdi2 \
+	_adddi3 _subdi3 _notdi2 _rotlhi3 _rotrhi3 \
 	_ashrhi3 _lshrhi3 _lshlhi3 _ashrqi3 _lshlqi3 _map_data _init_bss \
 	_ctor _dtor __far_trampoline
 
-- 
GitLab