question about lshiftrt:DI when there are no 64bits in the processor
fanqifei
fanqifei@gmail.com
Wed Sep 15 22:44:00 GMT 2010
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 <avr@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.
>
More information about the Gcc
mailing list