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")]) I can find out that the the insn is generated in pass_jump2(gcc/4.3.2/gcc/cfgcleanup.c). in p_b.c.137r.into_cfglayout: ;; Start of basic block ( 6) -> 5 ;; Pred edge 6 [97.1%] (code_label 69 44 47 5 57 "" [1 uses]) (note 47 69 50 5 [bb 5] NOTE_INSN_BASIC_BLOCK) (insn 50 47 48 5 p_b.c:491 (clobber (reg:DI 42 [ D.1783 ])) -1 (insn_list:REG_LIBCALL 51 (nil))) (insn 48 50 49 5 p_b.c:491 (set (subreg:SI (reg:DI 42 [ D.1783 ]) 0) (lshiftrt:SI (subreg:SI (reg/v:DI 35 [ k ]) 4) (const_int 0 [0x0]))) 54 {lshrsi3} (expr_list:REG_NO_CONFLICT (reg/v:DI 35 [ k ]) (nil))) (insn 49 48 51 5 p_b.c:491 (set (subreg:SI (reg:DI 42 [ D.1783 ]) 4) (const_int 0 [0x0])) 3 {*mov_mode_insn} (expr_list:REG_NO_CONFLICT (reg/v:DI 35 [ k ]) (nil))) (insn 51 49 52 5 p_b.c:491 (set (reg:DI 42 [ D.1783 ]) (reg:DI 42 [ D.1783 ])) 2 {movdi} (insn_list:REG_RETVAL 50 (expr_list:REG_EQUAL (lshiftrt:DI (reg/v:DI 35 [ k ]) (const_int 32 [0x20])) (nil)))) but in p_b.c.138r.jump, insns between 47 and 51 are removed and insn51 is changed. ;; Start of basic block ( 5) -> 4 ;; Pred edge 5 [97.1%] (code_label 69 44 47 4 57 "" [1 uses]) (note 47 69 51 4 [bb 4] NOTE_INSN_BASIC_BLOCK) (insn 51 47 52 4 p_b.c:491 (set (reg:DI 42 [ D.1783 ]) (lshiftrt:DI (reg/v:DI 35 [ k ]) (const_int 32 [0x20]))) 58 {*lshrdi3S1} (nil)) I am wondering what’s the usage of REG_EQUAL? ( I have read gcc internal, but still don’t quite understand). Why the instructions (47-51) are replaced by lshiftrt:DI when there is no lshrdi3 insn defined in md file? Thanks. -- -Qifei Fan