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]

Help with define_insn and constraints


Hi all,

I'm back again with another question about machine descriptions. Sorry
about all the questions, but I'm just starting out with md's and
there's a ton of information to absorb.

My machine description file has these instructions:

(define_insn "movqi"
	[(set (match_operand:QI 0 "nonimmediate_operand" "=m,m,r")
		  (match_operand:QI 1 "general_operand" "r,i,g"))]
  ""
  "MOVF %1,%0"
  [(set_attr "cc" "z")]
  )
  
(define_insn "addqi3"
	[(set (match_operand:QI 0 "register_operand" "=r,r")
		  (plus:QI (match_operand:QI 1 "register_operand" "%0,0")
                   (match_operand:QI 2 "nonmemory_operand" "r,i")))]
  ""
  "ADDF %1,%0"
  [(set_attr "cc" "all")]
  )

Also, the constraint "m" corresponds to this code in my machine.c/.h file:

#ifdef REG_OK_STRICT
#  define GO_IF_LEGITIMATE_ADDRESS(mode, operand, ADDR)	\
{							\
  if (legitimate_address_p (mode, operand, 1))		\
    goto ADDR;						\
}
#  else
#  define GO_IF_LEGITIMATE_ADDRESS(mode, operand, ADDR)	\
{							\
  if (legitimate_address_p (mode, operand, 0))		\
    goto ADDR;						\
}
#endif

int legitimate_address_p (enum machine_mode mode, rtx x, int strict)
{
  enum reg_class r = NO_REGS;
  
  /* Reg is OK */

	if (GET_CODE (x) == REG && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
                    : REG_OK_FOR_BASE_NONSTRICT_P (x)))
		r = ALL_REGS;
		
  /* Any constant address is OK */
  
  else if (CONSTANT_ADDRESS_P (x))
    r = ALL_REGS;
	
  /* Reg + const is OK */
    
  else if (GET_CODE (x) == PLUS
           && REG_P (XEXP (x, 0))
	   && GET_CODE (XEXP (x, 1)) == CONST_INT
	   && INTVAL (XEXP (x, 1)) >= 0)
	r = ALL_REGS;

  return r == NO_REGS ? 0 : (int)r;
}

So basically, we can have [ Rx ] or [ const ] or [ Rx + const ].

However, by the time gcc gets to reload_cse_simplify_operands, at
postreload.c:391, it is trying to match this insn, and fails, saying
"insn does not satisfy its constraints":

(insn 739 794 795 8 ../../Desktop/gcc-3.4.3/gcc/libgcc2.c:467 (set
(mem/f:QI (plus:QI (mem:QI (plus:QI (reg/f:QI 49 R20/FP)
                        (const_int 104 [0x68])) [6 S1 A8])
                (const_int 1 [0x1])) [2 <result>+1 S1 A8])
        (reg:QI 4 R53)) 0 {movqi} (nil)
    (nil))

In other words, [ [ R20 + 104 ] +1 ] <- R53. However, this is a double
indirection, and the "m" constraint only matches single indirection.
But I figured gcc would split this instruction automatically in two,
using a temporary register for the first indirection.

So my question is, why doesn't it, and how do I solve this problem? I
am having a hard time understanding when gcc has the built-in
intelligence to move things around, and when it does not.

Any advice or insight into this issue would be appreciated! Thanks
again for helping out a n00b :)

--Rob


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