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