------- Comment #2 from maxim at codesourcery dot com 2010-04-07 15:24 ------- The problem is in 68k_extendhisi2 pattern, second alternative: (define_insn "*68k_extendhisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,a") (sign_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "0,rmS")))] "!ISA_HAS_MVS_MVZ" "@ ext%.l %0 move%.w %1,%0" [(set_attr "type" "ext,move")])
Move.w instruction on ColdFire indeed preserves the upper bits, I found out that by luck in the coldfire uclinux kernel port, no reference manual that I know of spells out this behavior. I have a serious suspicion, though, that move.w on classic m68k does perform sign extension. Can anyone confirm this? If this is so, then the fix is to disable the second alternative when compiling for ColdFire, e.g., by setting attribute "ok_for_coldfire" to "no". -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43675