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

Re: move patterns, emit_move_insn


Florent DEFAY schrieb:
Thank you for your help.

Regarding your advice, I tried this implementation:

___________________________________________________
;; movhi
(define_expand "movhi"
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
        (match_operand:HI 1 "general_operand" "")
  )]
  ""
  ""
)

(define_insn "movhi1"
  [(set (match_operand:HI 0 "register_operand" "=r,r,m,r")
        (match_operand:HI 1 "general_operand" "r,m,r,i")
  )]
  ""
  "@
  movew\t%1,%0
  movew\t%1,%0
  movew\t%1,%0
  movew\t%1,%0"
)
____________________________________________________

But I get this error then:

e.c:7: error: unrecognizable insn:
(insn 7 6 8 3 e.c:4 (set (mem/c/i:HI (reg/f:HI 14) [0 i+0 S2 A16])
        (const_int 3 [0x3])) -1 (nil))

The expander may and will produce such patterns, but no insn matches because predicate 0 "register_operand" of movhi1 is too tight. Try wider predicate like "nonimmediate_operand"


I think GCC has to put immediate into memory. The arch can't do that
directly. GCC should put the immediate in register and then register
to memory.
Reload will do that. Emit two moves in the expander like this:

(define_expand "movhi"
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
        (match_operand:HI 1 "general_operand"      ""))]
  ""
  "
{
   /* One of the ops has to be in a register.  */
  if (!register_operand(operand0, HImode)
      && !(register_operand(operand1, HImode))
    {
      operands[1] = copy_to_mode_reg(HImode, operand1);
    }
}")

Georg-Johann


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