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.