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