[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gcc
Subject:    Re: pattern problem with register assignment
From:       Christian_Grössler <chris () groessler ! org>
Date:       2011-02-24 18:27:55
Message-ID: 4D66A32B.60001 () groessler ! org
[Download RAW message or body]

On 24.02.11 15:38, Jean-Marc Saffroy wrote:
> On 02/23/2011 09:52 PM, Christian Grössler wrote:
>> Hello,
>>
>> I have a problem with register allocation. Our architecture has some
>> pointer registers "pX" (24bit)
>> and some data registers "dX" (32bit). Since pointers are only 24bit,
>> we're using PSImode for them.
>>
>> There are restrictions in the "add" opcode, we can do
>>
>> pX = add(pX,<imm>)
>> pX = add(pX,dX)
>> pX = add(dX,pX)
>> dX = add(pX,pX)
>> dX = add(pX,<imm>)
>> dX = add(dX,dX)
>> dX = add(dX,<imm>)
>> dX = add(pX,dX)
>> dX = add(dX,pX)
>>
>> pX is allowed in at most 2 of the registers involved, but not in all 3
>> of them.
>> The pattern to add 2 PSImode values looks like this:
>>
>> (define_insn "*addpsi3"
>>    [(set (match_operand:PSI 0 "p_d_operand"
>> "=a,d0d3,?d0d9 m,?d0d9 m")
>>          (plus:PSI (match_operand:PSI 1 "p_d_general_operand"
>> "%a,d0d3,d0d9 a m,d0d9 a i")
>>            (match_operand:PSI 2 "p_d_general_operand" "i d0d9 m,d0d3 m
>> i,d0d9 i a,d0d9 a m")))]
>>    ""
>>    "%0=add(%1,%2)"
>> )
>>
>> It worked fine in the gcc version from 2 years ago, but I'm updating the
>> port to current gcc, and
>> I get a testsuite failure (one of many :-)) in
>> gcc.c-torture/compile/20080812-1.c:
>>
>> 20080812-1.c: In function 'foo':
>> 20080812-1.c:21:1: error: insn does not satisfy its constraints:
>> (insn 49 76 77 3 (set (reg:PSI 6 p2 [144])
>>          (plus:PSI (reg:PSI 5 p1 [orig:145 ivtmp.1 ] [145])
>>              (reg:PSI 7 p3))) 20080812-1.c:15 193 {*addpsi3}
>>       (nil))
>> 20080812-1.c:21:1: internal compiler error: in
>> reload_cse_simplify_operands, at postreload.c:401
>> Please submit a full bug report,
>> with preprocessed source if appropriate.
>> See<http://gcc.gnu.org/bugs.html>  for instructions.
>>
>>
>> It seems that gcc wants to create an instruction like "p2=add(p1,p3)".
>> How can I tell him not to do that?
>> I tried to fiddle with the "p_d_general_operand" predication and use a
>> modified one for operand 2, but
>> at the time the constraint is called, I only see pseudo registers, and
>> don't know in which hard register
>> they will appear at the end.
>>
>> I'm using a gcc snapshot from Jan-19-2011.
>>
>> regards,
>> chris
>>
>>
>
> FWIW, I faced a similar challenge for my private port (ie. define add
> for different types of registers), and I got gcc to work by defining a
> single pattern for all adds, with predicates that don't discriminate on
> register classes: the register contraints do the job of selecting the
> proper combinations.
>
> But there is probably more than one way to do it.
>
> Cheers,
> JM

Hmm, isn't it the same here? The predicates "p_d_general_operand" allow pX and dX
(and "general_operand"), and the constraints select which combinations are vaild.
I forgot to mention that "a" constraint means pX registers, and d0d9 and d0d3 refer
to d0-d9 and d0-d3 registers.

regards,
chris
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic