This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Register constraints + and =
On May 4, 2012, at 9:44 AM, Ian Lance Taylor wrote:
> "Paulo J. Matos" <paulo@matos-sorge.com> writes:
>
>> Expand generates:
>>
>> (define_insn_and_split "movmem_long"
>> [(set (match_operand:QI 2 "register_operand" "d,c") (const_int 0))
>> (set (mem:BLK (match_operand:QI 0 "register_operand" "d,c"))
>> (mem:BLK (match_operand:QI 1 "register_operand" "x,c")))
>> (set (match_dup 0) (plus:QI (match_dup 0) (match_dup 2)))
>> (set (match_dup 1) (plus:QI (match_dup 1) (match_dup 2)))
>> (clobber (match_scratch:QI 3 "w,w"))]
>> "!TARGET_NO_BLOCK_COPY"
>> "#"
>> "&& reload_completed"
>> [(const_int 0)]
>> {
>> if((which_alternative == 0 && REGNO(operands[2]) == RAH))
>> || which_alternative == 1)
>> {
>> emit_move_insn(operands[3], operands[0]);
>> emit_move_insn(operands[0], operands[2]);
>> emit_move_insn(operands[2], operands[3]);
>> }
>> emit_insn(gen_bc2());
>> DONE;
>> })
>>
>> From what I understand + is for input/output operands, = for output
>> only operands. Since in the above rule (a parallel) all operands are
>> written to and read to, does this mean all their constraints should
>> start with +? Or this only applies per set within each parallel (which
>> doesn't seem to make much sense)?
>
> I agree that there is something wrong here. I agree that as written
> the constraints for operands 0, 1, and 2 should have a '+'.
>
> That said, a '+' constraint is most useful for a pattern that expands
> into multiple instructions. I think this would be better written along
> the lines of
>
> (set (match_operand:QI 2 "register_operand" "=d,c") (const_int 0))
> (set (mem:BLK (match_operand:QI 3 "register_operand" "0")
> (match_operand:QI 4 "register_operand" "1")))
> (set (match_operand:QI 0 "register_operand" "=d,c")
> (plus:QI (match_dup 3)
> (match_operand:QI 5 "register_operand" "2"))))
> (set (match_operand:QI 1 "register_operand" "=x,c")
> (plus:QI (match_dup 4) (match_dup 5)))
> (clobber (match_scratch:QI 3 "=w,w"))
>
> Also it looks like it might be possible to add a third alternative such
> that that alternative does not require the match_scratch.
I thought that the "operand" in a mem:BLK is the pointer to the block, not the block itself. So if the instruction(s) generated don't touch the pointer -- a likely answer for a block-move instruction -- then the operand would be read-only. Is that the right interpretation?
What I ended up doing in pdp11.md is to add "clobber" clauses for the operands, because the generated code is typically a block-copy loop that steps the pointer registers through the buffer. It appeared to do the right thing, but I'll admit it was more of a "try this until it works" type of thing rather than a deep understanding of the precisely correct interpretation.
paul