summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorciceron <ciceron@138bc75d-0d04-0410-961f-82ee72b054a4>2003-03-02 20:04:27 +0000
committerciceron <ciceron@138bc75d-0d04-0410-961f-82ee72b054a4>2003-03-02 20:04:27 +0000
commit9ffd661f11e88f45057b1b54fa8996086da8be8f (patch)
tree0ef9b98630bafb452e8e53713d7ad883956f7692
parenta766fb276c0f26a35ad9b6e0986f39fd413c4355 (diff)
downloadgcc-9ffd661f11e88f45057b1b54fa8996086da8be8f.tar.gz
* 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
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/m68hc11/larith.asm43
-rw-r--r--gcc/config/m68hc11/m68hc11-protos.h3
-rw-r--r--gcc/config/m68hc11/m68hc11.c10
-rw-r--r--gcc/config/m68hc11/m68hc11.h1
-rw-r--r--gcc/config/m68hc11/m68hc11.md140
-rw-r--r--gcc/config/m68hc11/t-m68hc11-gas2
7 files changed, 184 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7f92216e79e..03eb0fac32e 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 80b88174737..0acf9122859 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 ec43ca0ac15..5bb69cf9851 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 6dafb198818..e99b844edea 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 c51f1924254..df4f8184e0c 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 92676c6af1d..8117d486973 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 1833fd56dc3..b5404cc8479 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