Thank you, Georg and Ian. I misunderstood the section16.2 of gcc internal manual and thought that the nameless insn (with * ) in .md file can be only used during rtl-->asm. The generated code is correct now.
Thanks again! -- -Qifei Fan On Wed, Sep 15, 2010 at 9:27 PM, Georg Lay <a...@gjlay.de> wrote: > fanqifei schrieb: >> Hi all, >> >> I am porting gcc to a microprocessor. There are no 64bits instructions >> in it. I added a small logical shift right optimization to the md >> file(see below). >> For the statement “k>>32” in which k is 64bits integer, the >> “define_expand” should fail because op2 is 32, not 1. >> However, I can see the lshiftrt:DI is still generated in rtl dumps >> even if I commented out the “define_expand”. If both “define_expand” >> and “define_isns” are commented out, the result is correct. >> >> .md file: >> >> ;; Special case for long x>>1, which can be expanded >> ;; using the carry bit shift-in instructions. x<<1 is already >> ;; expanded by the compiler into x+x, so no rules for long leftshift >> ;; necessary. >> ;; >> >> (define_expand "lshrdi3" >> [(set (match_operand:DI 0 "register_operand" ) >> (lshiftrt:DI (match_operand:DI 1 "register_operand") >> (match_operand:QI 2 "immediate_operand")))] >> "" >> { >> if ( GET_CODE(operands[2]) != CONST_INT ) { FAIL; } >> if ( INTVAL(operands[2]) != 1 ) { FAIL; } >> }) >> >> (define_insn "*lshrdi3S1" >> [(set (match_operand:DI 0 "register_operand" "=r") >> (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") >> (match_operand:QI 2 "immediate_operand" "i")))] >> "" >> "lsr.w %H0 %H1 1;\;lsrc.w %M0 %M1 1;" >> [(set_attr "cc" "clobber")]) > [...] >> Why the instructions (47-51) are replaced by lshiftrt:DI when there is >> no lshrdi3 insn defined in md file? > > You actually /have/ defined an insn that allows lshiftrt:DI patterns for any > constant (even constants that are not known at compile time), namely your > "*lshrdi3S1" insn. Note that many passes construct new RTL out of RTL already > generated and try to match these constructs against some insns, most notably > pass insn-combine, insn splitters. If there is no match nothing happens. If > there is a match (and costs are lower etc.) the old pattern gets replaced by > the > new one. In your case that means that you have to disallow anything that has > op2 > not equal to 1. So you couls rewrite the insn in question to > > (define_insn "*lshrdi3S1" > [(set (match_operand:DI 0 "register_operand" "=r") > (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") > (const_int 1)))] > "" > ...) > > or > > (define_insn "*lshrdi3S1" > [(set (match_operand:DI 0 "register_operand" "=r") > (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") > (match_operand:QI 2 "const_int_operand" "n")))] > "operands[2] == const1_rtx" > ...) > > or any formulation you prefer. >