------- Additional Comments From marekm at amelek dot gda dot pl 2005-03-13 10:10 ------- Subject: Re: unable to find a register to spill in class `POINTER_REGS'
On Sun, Mar 13, 2005 at 02:44:51AM -0000, andrewhutchinson at cox dot net wrote: > And with oxffff is wrong. As is trying to handle the variable count > case. That is fixing something that is not broke. Does this look OK? Now "movmemhi" will only handle positive constant counts, and FAIL for the other cases (zero, negative or variable) to let GCC handle them by itself. Hopefully this is the final version, committed to mainline - 4.0 and 3.4 will follow soon if there are no problems, please test. Thanks, Marek ;; move string (like memcpy) ;; implement as RTL loop (define_expand "movmemhi" [(parallel [(set (match_operand:BLK 0 "memory_operand" "") (match_operand:BLK 1 "memory_operand" "")) (use (match_operand:HI 2 "const_int_operand" "")) (use (match_operand:HI 3 "const_int_operand" ""))])] "" "{ int prob; HOST_WIDE_INT count; enum machine_mode mode; rtx label = gen_label_rtx (); rtx loop_reg; rtx jump; /* Copy pointers into new psuedos - they will be changed. */ rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); /* Create rtx for tmp register - we use this as scratch. */ rtx tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO); if (GET_CODE (operands[2]) != CONST_INT) FAIL; count = INTVAL (operands[2]); if (count <= 0) FAIL; /* Work out branch probability for latter use. */ prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count; /* See if constant fit 8 bits. */ mode = (count < 0x100) ? QImode : HImode; /* Create loop counter register. */ loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode)); /* Now create RTL code for move loop. */ /* Label at top of loop. */ emit_label (label); /* Move one byte into scratch and inc pointer. */ emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1)); emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx)); /* Move to mem and inc pointer. */ emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx); emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx)); /* Decrement count. */ emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx)); /* Compare with zero and jump if not equal. */ emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1, label); /* Set jump probability based on loop count. */ jump = get_last_insn (); REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob), REG_NOTES (jump)); DONE; }") -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18251