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