Hi, I am trying to alter a machine description to produce efficient instruction scheduling. Towards that goal, I am trying to eliminate every instance where a define_insn outputs more than one assembly instruction for given constraints. One of the operations that takes two assembly instructions is moving an immediate value that is represented by more than 16 bits into a 32 bit register. It is done by assigning the high and low halfwords each with unsigned 16 bit immediates. I tried to expand the single RTL move expression into two using the following define expand: (define_expand "movsi" [(set (match_operand:SI 0 "nonimmediate_operand" "") (match_operand:SI 1 "general_operand" ""))] "" { if(GET_CODE(operands[0]) != REG){ operands[1] = force_reg(SImode, operands[1]); } if(REG_P(operands[0]) && CONSTANT_P(operands[1]) && (-0x8000 > INTVAL(operands[1]) || INTVAL(operands[1]) > 0x7FFF)){ emit_move_insn(gen_rtx_SUBREG(HImode, operands[0], 2), GEN_INT((INTVAL(operands[1]) >> 16) & 0xFFFF)); emit_move_insn(gen_rtx_SUBREG(HImode, operands[0], 0), GEN_INT(INTVAL(operands[1]) & 0xFFFF)); DONE; } } ) I also added the following define_insn's to match the resulting RTL to assembly. (define_insn "movhi_subreg0" [(set (subreg:HI (match_operand:SI 0 "register_operand" "=r") 0) (match_operand:HI 1 "immediate_operand" "I"))] "" "%0.l = #%1" ) (define_insn "movhi_subreg1" [(set (subreg:HI (match_operand:SI 0 "register_operand" "=r") 2) (match_operand:HI 1 "immediate_operand" "I"))] "" "%0.h = #%1" ) When I try to build, I get the following error when the cross compiler tries to compile a file for the target: internal compiler error: in do_SUBST, at combine.c:446 >From what I can tell, it does not like when the low 16 bits have a 1 in the most significant bit. Can anyone tell me why this does not work? How could I get it to work? Is this the right approach at all? If what I am trying will not work, then how can I avoid outputting multiple assembly instructions at once? Thank you, Charles J. Tabony