This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: defining add in a new port
On 01/28/2011 09:45 PM, Ian Lance Taylor wrote:
> Jean-Marc Saffroy <jean-marc.saffroy@joguin.com> writes:
>
>> On 01/28/2011 06:44 PM, Ian Lance Taylor wrote:
>>> Jean-Marc Saffroy <jean-marc.saffroy@joguin.com> writes:
>>>
>>>> error: insn does not satisfy its constraints:
>>>> (insn 1424 1423 141 (set (reg:DI 2 r2)
>>>> (plus:DI (reg:DI 2 r2)
>>>> (const_int 40 [0x28])))
>>>> /home/jmsaffroy/cygnus/src/newlib/libc/time/strptime.c:165 24 {adddi3}
>>>> (expr_list:REG_EQUIV (plus:DI (reg/f:DI 70 a6)
>>>> (const_int 40 [0x28]))
>>>> (nil)))
>>>
>>> You should find out what is creating this insn. Is it being created by
>>> reload, or is it being created by some pass that runs after reload?
>>
>> With gcc -da, I see that it appears in dump .195r.ira, so that's reload,
>> right?
>
> Right.
>
>
>>> It is likely that you need to make adddi3 a define_expand which tests
>>> reload_in_progress and reload_completed. If those are the case, you
>>> will need to explicitly convert
>>> (set (reg:DI DREG1) (plus:DI (reg:DI DREG2) (const_int N)))
>>> into
>>> (set (reg:DI DREG1) (const_int N))
>>> (set (reg:DI DREG1) (plus:DI (reg:DI DREG1) (REG:DI DREG2)))
>>>
>>
>> Ah, but here it happens that DREG1 and DREG2 (r2 and a6 above) are
>> different types of registers, and I can't add them directly.
>
> The insn you showed is adding a constant to a DREG. There is no
> addition of a DREG and an AREG, and I would not expect reload to
> generate any such addition either. Are you looking at a different insn?
> Don't get confused by the REG_EQUIV note, it's irrelevant here.
Actually, looking at the full dumps, I see that this incorrect insn
shown in the ICE above is emitted when eliminating the arg pointer: a6
is the frame pointer (a6+40 probably points to the args on stack).
Running cc1 under gdb, I see that gen_reload is tasked with reloading
(plus AREG N) into (DREG): the first attempts fail (the generated insns
are rejected by emit_insn_if_valid_for_reload), and so gen_reload
recurses (reload.c:8550), generates a 2-insn sequence that does:
(set DREG AREG)
(set DREG (plus DREG N))
But this N is not a valid immediate for an add to a DREG, according to
the predicates I defined for adddi3, which are not checked at this
point, but only later on in final_scan_insn.
So it seems I will have to have adddi3 be a define_expand that splits
the increment by N into smaller increments when called with
(reload_in_progress||reload_completed). Does that sound reasonable?
It's worth noting that I'm developing with an old svn checkout of the
gcc trunk from last October, I will update ASAP just in case.
Jean-Marc