This is the mail archive of the 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]

Controlling instruction alternative selection

I'm working with a CPU having a restricted set of registers that can do three address maths wheres ALL registers can do two address maths.

If I define

(define_insn "addsi3"
  [     (set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (match_operand:SI 1 "register_operand" "0,0") (match_operand:SI 2 "rhs_operand" "r,i")))

So that all adds are done using 2 address instructions then all is fine. If however I change addsi3 to

(where the constraint 'R' is the smaller set of three address registers)

(define_insn "addsi3"
  [     (set (match_operand:SI 0 "register_operand" "=R,r,r")
(plus:SI (match_operand:SI 1 "register_operand" "R,0,0") (match_operand:SI 2 "rhs_operand" "R,r,i")))

to take advantage of the three address instructions then the three address instructions are used successfully on many occassions.

However when register pressure on the 'R' class is high the allocater never falls back to using the entire register set by employing the two address instructions.

Resulting in ...

error: unable to find a register to spill in class âGP_REGSâ

enabling lra and inspecting the rtl dump indicates that both alternatives (R and r) seem to be equally appealing to the allocater so it chooses 'R' and fails.

GCC internals document indicates that the '0' alternates should be placed at the end of the alternatives list, so I'm guessing 'R' will always be chosen.

Using constraint disparaging (?R) eradicates the errors, but of course that causes the 'R' three address alternative to never be used.

Suggestions ?

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