From 73035bf942d9bf35e7b2eaa6eadfe15e53963845 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sun, 8 May 2005 20:54:51 +0200 Subject: [PATCH] m68hc11.c (m68hc11_z_replacement): Use emit_insn_after when adding the save Z instruction so that it is part of... * config/m68hc11/m68hc11.c (m68hc11_z_replacement): Use emit_insn_after when adding the save Z instruction so that it is part of the good BB. (reg_or_some_mem_operand): Do not allow the 68HC12 address indirect addressing mode as it is not supported by bset and bclr. (m68hc11_gen_movhi): Fix invalid generation of indexed indirect addressing with movw. (m68hc11_gen_movqi): Use pula and pulb instead of lda and ldb for 68HC12. * config/m68hc11/m68hc11.md ("movhi_const0"): Use this pattern only for 68HC11. ("*movhi_68hc12"): Handle movhi_const0. ("*subhi3", "subqi3"): Use general_operand for operand 1. ("*subhi3_zext"): Likewise. From-SVN: r99402 --- gcc/ChangeLog | 16 +++++ gcc/config/m68hc11/m68hc11.c | 112 +++++++++++++++++++++++++---------- 2 files changed, 98 insertions(+), 30 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a8fc36914d10..b75e41f7d22d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2005-05-08 Stephane Carrez + + * config/m68hc11/m68hc11.c (m68hc11_z_replacement): Use emit_insn_after + when adding the save Z instruction so that it is part of the good BB. + (reg_or_some_mem_operand): Do not allow the 68HC12 address indirect + addressing mode as it is not supported by bset and bclr. + (m68hc11_gen_movhi): Fix invalid generation of indexed indirect + addressing with movw. + (m68hc11_gen_movqi): Use pula and pulb instead of lda and ldb for + 68HC12. + * config/m68hc11/m68hc11.md ("movhi_const0"): Use this pattern only + for 68HC11. + ("*movhi_68hc12"): Handle movhi_const0. + ("*subhi3", "subqi3"): Use general_operand for operand 1. + ("*subhi3_zext"): Likewise. + 2005-05-08 Stephane Carrez PR target/19051 diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c index 8f054622c03e..383025d4ae15 100644 --- a/gcc/config/m68hc11/m68hc11.c +++ b/gcc/config/m68hc11/m68hc11.c @@ -1027,6 +1027,7 @@ reg_or_some_mem_operand (rtx operand, enum machine_mode mode) if (GET_CODE (operand) == MEM) { rtx op = XEXP (operand, 0); + int addr_mode; if (symbolic_memory_operand (op, mode)) return 1; @@ -1034,10 +1035,20 @@ reg_or_some_mem_operand (rtx operand, enum machine_mode mode) if (IS_STACK_PUSH (operand)) return 1; - if (m68hc11_register_indirect_p (operand, mode)) - return 1; + if (GET_CODE (operand) == REG && reload_in_progress + && REGNO (operand) >= FIRST_PSEUDO_REGISTER + && reg_equiv_memory_loc[REGNO (operand)]) + { + operand = reg_equiv_memory_loc[REGNO (operand)]; + operand = eliminate_regs (operand, 0, NULL_RTX); + } + if (GET_CODE (operand) != MEM) + return 0; - return 0; + operand = XEXP (operand, 0); + addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0); + addr_mode &= ~ADDR_INDIRECT; + return register_indirect_p (operand, mode, addr_mode); } return register_operand (operand, mode); @@ -3221,10 +3232,13 @@ m68hc11_gen_movhi (rtx insn, rtx *operands) if (TARGET_M6812) { - if (IS_STACK_PUSH (operands[0]) && H_REG_P (operands[1])) + rtx from = operands[1]; + rtx to = operands[0]; + + if (IS_STACK_PUSH (to) && H_REG_P (from)) { cc_status = cc_prev_status; - switch (REGNO (operands[1])) + switch (REGNO (from)) { case HARD_X_REGNUM: case HARD_Y_REGNUM: @@ -3239,10 +3253,10 @@ m68hc11_gen_movhi (rtx insn, rtx *operands) } return; } - if (IS_STACK_POP (operands[1]) && H_REG_P (operands[0])) + if (IS_STACK_POP (from) && H_REG_P (to)) { cc_status = cc_prev_status; - switch (REGNO (operands[0])) + switch (REGNO (to)) { case HARD_X_REGNUM: case HARD_Y_REGNUM: @@ -3273,11 +3287,52 @@ m68hc11_gen_movhi (rtx insn, rtx *operands) else output_asm_insn ("st%1\t%0", operands); } + + /* The 68hc12 does not support (MEM:HI (MEM:HI)) with the movw + instruction. We have to use a scratch register as temporary location. + Trying to use a specific pattern or constrain failed. */ + else if (GET_CODE (to) == MEM && GET_CODE (XEXP (to, 0)) == MEM) + { + rtx ops[4]; + + ops[0] = to; + ops[2] = from; + ops[3] = 0; + if (dead_register_here (insn, d_reg)) + ops[1] = d_reg; + else if (dead_register_here (insn, ix_reg)) + ops[1] = ix_reg; + else if (dead_register_here (insn, iy_reg)) + ops[1] = iy_reg; + else + { + ops[1] = d_reg; + ops[3] = d_reg; + output_asm_insn ("psh%3", ops); + } + + ops[0] = to; + ops[2] = from; + output_asm_insn ("ld%1\t%2", ops); + output_asm_insn ("st%1\t%0", ops); + if (ops[3]) + output_asm_insn ("pul%3", ops); + } + + /* Use movw for non-null constants or when we are clearing + a volatile memory reference. However, this is possible + only if the memory reference has a small offset or is an + absolute address. */ + else if (GET_CODE (from) == CONST_INT + && INTVAL (from) == 0 + && (MEM_VOLATILE_P (to) == 0 + || m68hc11_small_indexed_indirect_p (to, HImode) == 0)) + { + output_asm_insn ("clr\t%h0", operands); + output_asm_insn ("clr\t%b0", operands); + } else { - rtx from = operands[1]; - rtx to = operands[0]; - if ((m68hc11_register_indirect_p (from, GET_MODE (from)) && !m68hc11_small_indexed_indirect_p (from, GET_MODE (from))) || (m68hc11_register_indirect_p (to, GET_MODE (to)) @@ -3294,6 +3349,7 @@ m68hc11_gen_movhi (rtx insn, rtx *operands) ops[0] = to; ops[1] = operands[2]; m68hc11_gen_movhi (insn, ops); + return; } else { @@ -3301,19 +3357,11 @@ m68hc11_gen_movhi (rtx insn, rtx *operands) fatal_insn ("move insn not handled", insn); } } - else - { - if (GET_CODE (from) == CONST_INT && INTVAL (from) == 0) - { - output_asm_insn ("clr\t%h0", operands); - output_asm_insn ("clr\t%b0", operands); - } - else - { - m68hc11_notice_keep_cc (operands[0]); - output_asm_insn ("movw\t%1,%0", operands); - } - } + else + { + m68hc11_notice_keep_cc (operands[0]); + output_asm_insn ("movw\t%1,%0", operands); + } } return; } @@ -3641,8 +3689,10 @@ m68hc11_gen_movqi (rtx insn, rtx *operands) } else if (H_REG_P (operands[0])) { - if (Q_REG_P (operands[0])) - output_asm_insn ("lda%0\t%b1", operands); + if (IS_STACK_POP (operands[1])) + output_asm_insn ("pul%b0", operands); + else if (Q_REG_P (operands[0])) + output_asm_insn ("lda%0\t%b1", operands); else if (D_REG_P (operands[0])) output_asm_insn ("ldab\t%b1", operands); else @@ -5006,9 +5056,11 @@ m68hc11_z_replacement (rtx insn) if (info.save_before_last) save_pos_insn = PREV_INSN (save_pos_insn); - emit_insn_before (gen_movhi (gen_rtx (REG, HImode, SOFT_Z_REGNUM), - gen_rtx (REG, HImode, info.regno)), - save_pos_insn); + /* Use emit_insn_after () to ensure the new insn is part of + the good basic block. */ + emit_insn_after (gen_movhi (gen_rtx (REG, HImode, SOFT_Z_REGNUM), + gen_rtx (REG, HImode, info.regno)), + PREV_INSN (save_pos_insn)); } if (info.must_push_reg && info.last) @@ -5047,8 +5099,8 @@ m68hc11_z_replacement (rtx insn) else dst = gen_rtx (REG, HImode, SOFT_SAVED_XY_REGNUM); - emit_insn_before (gen_movhi (gen_rtx (REG, HImode, info.regno), - dst), insn); + emit_insn_after (gen_movhi (gen_rtx (REG, HImode, info.regno), + dst), PREV_INSN (insn)); } } -- 2.47.2