diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7f92216e79e7cd12613edafd04595c171ff5d28b..03eb0fac32ee455c9fbeac23dd0ac70ba734d09d 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 80b881747370dcf7f9ec63a9b8f3b3bd5e47ac08..0acf91228597655d5cf82aa72f4c472e4caddc62 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 ec43ca0ac1563c86155f9cfad2a3db02a1509110..5bb69cf98517b0e00abb12301647faf166827edb 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 6dafb1988185420399ff4d383b9bde7f961432b0..e99b844edea2364304e4b8d1aa659bfb3266ffb9 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 c51f19242549805acec32bc7ca4b977e663faf09..df4f8184e0c79e51ed976afe9eda16277e1eeea9 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 92676c6af1de14bb6fab436db1e8ae47d82895e1..8117d486973991b9eaec500739c1c6430f82709c 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 1833fd56dc335b5d9fb4b456be011ebe7c933729..b5404cc84797347d76f8f0c66c9a93e1fc25a679 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