memory predicate in RTL pattern
daniel tian
daniel.xntian@gmail.com
Mon Dec 21 02:55:00 GMT 2009
Hi,
I have a problem with load/store pattern. Because in my target,
the load/store memory operand must like this form: (MEM: (REG) ),
(MEM: (REG + CONST_INT)), (MEM: (REG + REG)).
const_int should less than 256. But in CALL insn, the memory operand
can should be in (MEM: (REG)), (MEM:(SYMBOL_REF)). I just wanna to
avoid the RTX expression (MEM:(CONST)) ,(MEM:(SYMBOL_REF)),
(MEM:(LABEL_REF)) in load/store from/to memory insns. That's what I
was puzzled.
Now I have already generate the right RTL in "move<mode>"
define_expand pattern. when the memory operand is const (whatever
CONST, SYMBOL_REF, LABEL_REF), I will force the constant address into
register first, then generate the memory operand with this register,
and finally, with this memory operand, load/store insns are created:
reg <--- CONSTANT_ADDRESS
MEM:(reg)
SET REG MEM
SET MEM REG
So I defined the following insn pattern in MD file:
(define_mode_iterator GPR [QI HI SI])
;;store to memory
(define_insn "store_<mode>"
[(set (match_operand:GPR 0 "memory_operand" "=m")
;; [(set (mem:GPR (match_operand:SI 0 "rice_addr_operand" "T"))
(match_operand:GPR 1 "rice_gpr_operand" "x"))]
"TARGET_RICE"
{
return rice_output_move (operands, <MODE>mode);
}
)
;;Load memory
(define_insn "load_<mode>"
[(set (match_operand:GPR 0 "rice_gpr_operand" "=x")
;; (mem:GPR (match_operand:SI 1 "rice_addr_operand" "T")))]
(match_operand:GPR 1 "memory_operand" "m"))]
"TARGET_RICE"
{
return rice_output_move (operands, <MODE>mode);
}
[(set_attr "type" "load")]
)
predicate "rice_addr_operand" is defined in rice.c here:
int rice_addr_operand(rtx op, enum machine_mode mode)
{
if(GET_CODE(op) == REG)
{
return REG_OK_FOR_BASE_P(op);
}
if(GET_CODE(op) == PLUS)
{
rtx op1=XEXP(op, 0);
rtx op2=XEXP(op, 1);
if((GET_CODE(op1) == REG && GET_CODE(op2) == CONST_INT))
{
return REG_OK_FOR_BASE_P(op1)
&& Bit8_constant_operand(op2, SImode);
}
if((GET_CODE(op1) == REG && GET_CODE(op2) == REG))
{
return REG_OK_FOR_BASE_P(op1)
&& REG_OK_FOR_INDEX_P(op2);
}
if(GET_CODE(op1) == CONST_INT && GET_CODE(op2) == REG)
{
return REG_OK_FOR_BASE_P(op2)
&& Bit8_constant_operand(op1, SImode);
}
}
return RICE_NO;
}
constraint "T" is define in target macro "EXTRA_CONSTRAINT"
corresponding to predicate "rice_addr_operand".
((ch) == 'S' ? symbolic_operand(x, GET_MODE(x)) :
(ch) == 'Q' ? CONSTANT_ADDRESS_P(x) :
(ch) == 'Y' ? movi_constant_operand(x, GET_MODE(x)):
(ch) == 'T' ? rice_addr_operand(x, GET_MODE(x)): 0);
But cc1 can't compile libgcc2.c successfully.
But the operands can't satisfy operand constraint. Like the following(
it is in libgcc2.c.175r.lreg):
(insn:HI 98 5 22 2 ../../../rice-gcc-4.3.0/libgcc/../gcc/libgcc2.c:558
(set (reg/f:SI 32 virtual-stack-vars)
(const_int 0 [0x0])) 2 {constant_load_si} (expr_list:REG_EQUAL
(const_int 0 [0x0])
(nil)))
But in libgcc2.c.176r.greg, reload process occurred:
(insn:HI 98 5 103 2
../../../rice-gcc-4.3.0/libgcc/../gcc/libgcc2.c:558 (set (reg:SI 4 R4)
(const_int 0 [0x0])) 2 {constant_load_si} (expr_list:REG_EQUAL
(const_int 0 [0x0])
(nil)))
(insn 103 98 22 2 ../../../rice-gcc-4.3.0/libgcc/../gcc/libgcc2.c:558
(set (reg/f:SI 32 virtual-stack-vars)
(reg:SI 4 R4)) 14 {move_regs_si} (nil))
the insn 103 can't be satisfy move_regs_si's constraint. when
reload_completed, the pseduo register should be no longer existed.
But it is, so error happens.
But when I revise the load/store insn pattern in MD file like this:
;;store
(define_insn "store_<mode>"
[(set (match_operand:GPR 0 "memory_operand" "=m")
;; [(set (mem:GPR (match_operand:SI 0 "rice_addr_operand" "T"))
(match_operand:GPR 1 "rice_gpr_operand" "x"))]
"TARGET_RICE && (!CONSTANT_ADDRESS_P(XEXP(operands[0], 0)))"
{
return rice_output_move (operands, <MODE>mode);
}
)
;;Load
(define_insn "load_<mode>"
[(set (match_operand:GPR 0 "rice_gpr_operand" "=x")
;; (mem:GPR (match_operand:SI 1 "rice_addr_operand" "T")))]
(match_operand:GPR 1 "memory_operand" "m"))]
"TARGET_RICE && (!CONSTANT_ADDRESS_P(XEXP(operands[1], 0)))"
{
return rice_output_move (operands, <MODE>mode);
}
[(set_attr "type" "load")]
)
gcc works fine.
I just don't know why the former solution can't work correctly, and
still don't know much
of the predicate "memory_operand", "address_operand".
I mean why I can't write my own predicate function just like the
"memory_operand", "address_operand" do.
Is the reload process making the two predicate function complex?
Can anybody give me some advice?
Any suggestion is appreciated.
Thanks very much.
danie.tian
More information about the Gcc
mailing list