"Omar Torres" <[EMAIL PROTECTED]> writes:
> Richard Sandiford wrote:
>> Also, you need to beware of cases in which operands[1] overlaps
>> operands[0].  The splitter says:
>>
>>  [(set (match_dup 2) (match_dup 4))
>>   (set (match_dup 3) (match_dup 5))]
>>
>> and operands[2] is always the highpart:
>>
>>    operands[2] = gen_highpart(QImode, operands[0]);
>>
>> but consider the case in which operands[1] (and thus operands[4])
>> is a memory reference that uses the high part of operands[0] as
>> a base register.  In that case, the base register will be modified
>> by the first split instruction and have the wrong value in the
>> second split instruction.  See other ports for the canonical way
>> of handling this.
>>
>> Richard
>
> By looking at other ports, I learned that I can detect when this happens
> by using the reg_overlap_mentioned_p(). Here is one case:
> (insn 43 115 74 (set (reg:HI 7 %i0h)
>          (mem/s/j:HI (plus:HI (reg/f:HI 7 %i0h [orig:39 source ] [39])
>                  (const_int 2 [0x2])) [0 <variable>.r+0 S2 A8])) 3
> {*movhi} (nil)
>      (nil))
>
>    I need to tell the compiler not to use as destination the same base
> register when doing index operations. Any suggestions on how do I that?

Hmm.  If one destination register is the base and the other is the
index, you're probably best off adding them together and freeing up
a register that way.  Hopefully it'll be a rare case.

Because you're doing this in a splitter, some of the later
rtl optimisers _might_ be able to get rid of the addition,
but I wouldn't bet on it.

Richard

Reply via email to