This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: pattern problem with register assignment


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]