Help with constraint for single register

Robert Baruch autophile@gmail.com
Sun Dec 26 01:01:00 GMT 2004


On Fri, 24 Dec 2004 23:28:00 -0500, Robert Baruch <autophile@gmail.com> wrote:

> I think I may have to use some kind of define_expand, which accepts
> any operands, and have it emit RTL to convert to operations the
> processor can handle...

I tried this idea, and it seemed to work in a limited way. First, I
removed the W register from the GENERAL_REGS class, and made it part
of a RESERVED_REGS class. Registers in RESERVED_REGS will only be used
by me in expands or peepholes. GCC should never take control of these
registers for any purpose (except for optimization).

So now, I defined an expander:

(define_expand "movqi"
	[(set (match_operand:QI 0 "nonimmediate_operand" "")
		  (match_operand:QI 1 "general_operand" ""))]
  ""
  "
  {
    /* generate insns for op1 -> W, W -> op2 */
    DONE;
  }

QUESTION #1: Since I'm always going to use DONE, do I really have to
define an RTL template here? Or can I leave it empty? Should I leave
it in just for documentation purposes?


Next, I have a define_insn for *movqi, which can only be passed moves
through W. If there's a move that does not involve W, we better debug
that situation.

QUESTION #2: Uh oh, somehow the compiler got a hold of W anyway, and
generated RTL for const -1 -> W, and passed that move to my expander.
How did the compiler grab W? I didn't include it in GENERAL_REGS.
Here's an excerpt of the register masks:

  {0x00000001, 0x00000000}, /* W_REG */				\
  {0x00000001, 0x00380000}, /* RESERVED_REGS */	\
  {0xFFFFFFFE, 0x0007FFFF}, /* GENERAL_REGS */	\
  {0xFFFFFFFF, 0x003FFFFF}  /* ALL_REGS */			\


Thanks for any help you can give,

--Rob



More information about the Gcc mailing list