This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Help with define_insn and constraints
- From: Robert Baruch <autophile at gmail dot com>
- To: gcc at gcc dot gnu dot org
- Date: Thu, 23 Dec 2004 11:58:54 -0500
- Subject: Help with define_insn and constraints
- Reply-to: Robert Baruch <autophile at gmail dot com>
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