Hi All,
  Since the architecture I am working with only support byte size moves,
I created a define_split break HI-move insn's into two  QI-moves.

For example, the following insn:
(insn 84 5 9 (set (reg:HI 1 %r3)
         (const_int 32767 [0x7fff])) 3 {*movhi} (nil)
     (nil))

I split it into:
(set (reg:QI 1 %r3)
      (const_int 127 [0x7f])
(set (reg:QI 2 %r2)
      (const_int 255 [0x255])

I expect that the simplified RTL will be detected by the movqi pattern:
(define_insn "movqi"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,m")
        (match_operand:QI 1 "general_operand"      "g,r"))]
   ""
   "move\t%0,%1")


The split split is working as I expect, but the problem is that the
movqi is not recognizing the the second part of the move:
error: unrecognizable insn:
(insn 94 93 9 (set (reg:QI 2 %r2 [orig:1+1 ] [1])
         (const_int 255 [0xff])) -1 (nil)
     (nil))


After further investigating this, I was able find why the movqi is not
recognizing this patter. The const_int 255 fails this statement in the
general_operand predicate:
   if (GET_CODE (op) == CONST_INT
       && mode != VOIDmode
       && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
     return 0;
When I debug this I can see that trunc_int_for_mode is returning -1
while the INTVAL macro returns 255.

Any suggestions on how to fix this issue?

Below is the complete define_split I am referring above.

(define_split
   [(set (match_operand:HI 0 "nonimmediate_operand" "")
         (match_operand:HI 1 "general_operand"      ""))]
   "reload_completed
    && REG_P (operands[0])"
[(set (match_dup 2) (match_dup 4))
  (set (match_dup 3) (match_dup 5))]
  "{
   gcc_assert (REG_P (operands[0]));
   operands[2] = gen_highpart(QImode, operands[0]);
   operands[3] = gen_lowpart (QImode, operands[0]);

   if (REG_P (operands[1])) {
       operands[4] = gen_highpart (QImode, operands[1]);
       operands[5] = gen_lowpart  (QImode, operands[1]);
   }
   else if (MEM_P (operands[1]) || CONST == GET_CODE (operands[1])) {
       int ioff;
       rtx base, off;
       base = XEXP (operands[1],0);
       off  = gen_rtx_CONST_INT (VOIDmode, 0);
       if (CONST == GET_CODE (base)) {
           base = XEXP(base,0);
       }
       if (PLUS == GET_CODE (base)) {
        off  = XEXP (base,1);
        base = XEXP (base,0);
       }
       gcc_assert (REG == GET_CODE (base)
                   && CONST_INT == GET_CODE (off));
       ioff = INTVAL (off);
       gcc_assert (254 >= ioff
                   && 0 <= ioff);
       operands[4] = gen_rtx_MEM (QImode,
                                  gen_rtx_PLUS (Pmode,
                                                base,
                                                gen_rtx_CONST_INT               
                                            (QImode, ioff + 1)));
       operands[5] = gen_rtx_MEM (QImode,
                                  gen_rtx_PLUS (Pmode,
                                                base,

gen_rtx_CONST_INT(QImode, ioff)));
   }
   else if (LABEL_REF == GET_CODE (operands[1])
          || SYMBOL_REF == GET_CODE (operands[1])) {
       operands[4] = simplify_gen_subreg(QImode,operands[1],HImode,0);
       operands[5] = simplify_gen_subreg(QImode,operands[1],HImode,1);
   }
   else if (CONST_INT == GET_CODE (operands[1])) {
       int val = INTVAL (operands[1]);
       int low = val & 0xff;
       int high = (val>>8) & 0xff;
       operands[4] = gen_rtx_CONST_INT (QImode, high);
       operands[5] = gen_rtx_CONST_INT (QImode, low);
   }
   else {
       fprintf (stderr, \"\nUnrecongnized:\");
       debug_rtx (operands[1]);
   }
  }")


Thanks,
-Omar

Reply via email to