Hi, I have been working on very similar issues for the avr target. You might have a look at the patch I have posted today and the corresponding discussion thread at the gcc-patches list.
I have also observed, that gen_highpart and gen_lowpart sometimes causes an ICE for reasons. ... did not figure out so far why. I'd like to suggest that a pattern that might help you is simply (set (subreg:HI (match_dup 0) 0) (match_dup 2) (set (subreg:HI (match_dup 0) 2) (match_dup 3) with the preparation statements int full_value = INTVAL( operands[1]); int lsw_value = full_value & 0x0000FFFF; if (lsw_value & 0x8000) lsw_value -= 0x00010000; // lsw_value must be in the range of -32768 ... 32767! int msw_value = (full_value >> 16) & 0x0000FFFF; if (msw_value & 0x8000) msw_value -= 0x00010000; // msw_value must be in the range of -32768 ... 32767! operands[2] = GEN_INT(lsw_value); operands[3] = GEN_INT(msw_value); . Be aware that your immediate operand might be a label reference so that INTVAL will fail on it since it is not known at compile time. The only workaround I have found so far for treating this case of label reference immediates is: do not to split the instruction but to keep the unsplittet insn until instruction emission. You also probably will whish to handle the cases explitly that either msw_value or lsw_value happen to be zero so that you will not use the standard template but emit the RTL by yourself (for examples you might look at my patch for AVR). Yours, Björn