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.
>

Reply via email to