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