From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26561 invoked by alias); 13 Mar 2005 02:44:57 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 26498 invoked by alias); 13 Mar 2005 02:44:51 -0000 Date: Sun, 13 Mar 2005 02:44:00 -0000 Message-ID: <20050313024451.26497.qmail@sourceware.org> From: "andrewhutchinson at cox dot net" To: gcc-bugs@gcc.gnu.org In-Reply-To: <20041031125117.18251.ralf_corsepius@rtems.org> References: <20041031125117.18251.ralf_corsepius@rtems.org> Reply-To: gcc-bugzilla@gcc.gnu.org Subject: [Bug target/18251] unable to find a register to spill in class `POINTER_REGS' X-Bugzilla-Reason: CC X-SW-Source: 2005-03/txt/msg01565.txt.bz2 List-Id: ------- Additional Comments From andrewhutchinson at cox dot net 2005-03-13 02:44 ------- Subject: Re: unable to find a register to spill in class `POINTER_REGS' This is a define EXPAND. predicates (such as const_int_operand) and pattern have no effect at all on generated code or matching. This pattern always emits DONE or FAIL. That is why you need to test operand in body. And with oxffff is wrong. As is trying to handle the variable count case. That is fixing something that is not broke. So looks like my patch is ok? schlie at comcast dot net wrote: >------- Additional Comments From schlie at comcast dot net 2005-03-13 02:06 ------- >(In reply to comment #20) > >with reference to the most recent patch: >- anding with 0xFFFF may turn negatives positive so it seems wrong. >- there's no need limit byte counts to below 0x100 for bytes, as 0xFF is a > count as long is it was originally verifed that the integer value is positive. > >And just as a heads up, from when I was fooling a differnt varant, discovered >that (use (match_operand:HI 2 "const_int_operand" "")) apparently >also matches variable operands when compiling avrlibc: > >Apparently failing as no code is generated: > >../../../../libc/stdlib/realloc.c:154: error: unrecognizable insn: >(insn 235 232 236 31 ../../../../libc/stdlib/realloc.c:151 (parallel [ > (set (mem:BLK (reg/v/f:HI 49 [ memp ]) [0 A8]) > (mem:BLK (reg/v/f:HI 60 [ ptr ]) [0 A8])) > (use (reg:HI 81 [ .sz ])) > (use (const_int 1 [0x1])) > ]) -1 (insn_list:REG_DEP_TRUE 232 (nil)) > (expr_list:REG_DEAD (reg:HI 81 [ .sz ]) > (expr_list:REG_DEAD (reg/v/f:HI 49 [ memp ]) > (nil)))) > >>>From the following yet another version of Andy's patch: > >(and for the hell of it, enclosed at the end, a version which > attempts to handle variable counts, but couldn't figure out > how to get the conditional insertion of a forward branch > label generated correctly:) > >- won't emit code unless (count > 0). > >- removes code for non-constant count moves; as it would have > generated incorrect code for move count <= 0. > >- allocates a temporary, rather than presuming r0 is safe to use. > (and seems to generate just as good code, as a step to freeing r0) > >-- def -- > >;; 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 cnt8, prob; > enum machine_mode mode; > > rtx loop_reg; > rtx label = gen_label_rtx (); > > /* 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)); > > /* If loop count is constant, try to use QImode counter. */ > if ((GET_CODE (operands[2]) == CONST_INT) && (INTVAL (operands[2]) > 0)) > { > /* See if constant fit 8 bits. */ > cnt8 = byte_immediate_operand (operands[2], GET_MODE (operands[2])); > mode = cnt8 ? QImode : HImode; > > /* Create loop counter register. */ > loop_reg = copy_to_mode_reg (mode, gen_int_mode (INTVAL (operands[2]), > mode)); > > /* Create RTL code for move loop, with label at top of loop. */ > emit_label (label); > > /* Move one byte into scratch and inc pointer. */ > rtx tmp_reg = copy_to_mode_reg (QImode, gen_rtx_MEM (QImode, addr1)); > emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx)); > > /* Move scratch into mem, and inc other pointer. */ > emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg); > 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. */ > rtx jump = get_last_insn (); > prob = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / INTVAL (operands[2])); > REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob), > REG_NOTES (jump)); > DONE; > }}") > >This time attempting to handle variable counts: > >;; 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" ""))] )] > "" > "{ > enum machine_mode mode = HImode; > int prob = (REG_BR_PROB_BASE * 95) / 100; > rtx test_label = 0; /* Initial no-test value. */ > > /* Specify default variable loop count initial value. */ > rtx loop_cnt = copy_to_mode_reg (mode, operands[2]); > > /* Only generate code for variable, or constant counts != 0. */ > if ((GET_CODE (operands[2]) == CONST_INT) && (INTVAL (operands[2]) == 0)) > goto done; > > if (GET_CODE (operands[2]) == CONST_INT) /* A constant count. */ > { > /* Adjust loop count mode size as a function of const size. */ > if (byte_immediate_operand (operands[2], GET_MODE (operands[2]))) > { > mode = QImode; > } > /* Adjust jump probability based on known loop count. */ > prob = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / INTVAL (operands[2])); > /* Update intermediate loop_cnt value based on its mode size. */ > loop_cnt = copy_to_mode_reg (mode, gen_int_mode (INTVAL (operands[2]), > mode)); > } > else /* A variable count. */ > { >#if 0 /* FIXME, should jump to test_label if loop_cnt is a variable. */ > /* Specify first jump to test_label to verify loop_cnt != 0. */ > test_label = gen_label_rtx (); > emit_jump_insn (test_label); >#endif > } > > /* Specify memory operand pointer registers. */ > rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); > rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); > > /* Specify RLT loop, beginning with loop_label. */ > rtx loop_label = gen_label_rtx (); > emit_label (loop_label); > > /* Specify move one byte into scratch and inc pointer. */ > rtx tmp_reg = copy_to_mode_reg (QImode, gen_rtx_MEM (QImode, addr1)); > emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx)); > > /* Specify move scratch into mem, and inc other pointer. */ > emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg); > emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx)); > > /* Decrement count. */ > emit_move_insn (loop_cnt, gen_rtx_PLUS (mode, loop_cnt, constm1_rtx)); > >#if 0 /* FIXME, should specify initial variable loop_cnt test_label. */ > /* Specify test label, conditionally defined if loop_cnt = variable. */ > if (test_label) emit_label (test_label); should work as test_label. >#endif > > /* Compare with zero and loop if not-equal. */ > emit_cmp_and_jump_insns (loop_cnt, const0_rtx, NE, NULL_RTX, mode, 1, > loop_label); > > /* Set jump probability based on loop count. */ > rtx jump = get_last_insn (); > REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob), > REG_NOTES (jump)); > > DONE; > done: > }") > > > > -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18251