This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Splitting an immediate using define_expand


I am trying to separate move immediates that require more than 16 bits
into two instructions that set the high and low 16 bits of a register
respectively.  Here is my 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]);
    else if(CONSTANT_P(operands[1])
            && (-0x8000 > INTVAL(operands[1]) || INTVAL(operands[1]) >
      emit_move_insn(gen_rtx_SUBREG(HImode, operands[0], 0),
                     gen_rtx_TRUNCATE(HImode, operands[1]));
      emit_move_insn(gen_rtx_SUBREG(HImode, operands[0], 2),
                     gen_rtx_TRUNCATE(HImode, gen_rtx_LSHIFTRT(SImode,

and here are the patterns I intend to match:

(define_insn "movsi_subreg0"
  [(set (subreg:HI (match_operand:SI 0 "register_operand" "=r") 0)
        (truncate:HI (match_operand:SI 1 "immediate_operand" "i")))]
  "%0.l = #LO(%1)"

(define_insn "movsi_subreg1"
  [(set (subreg:HI (match_operand:SI 0 "register_operand" "=r") 2)
        (truncate:HI (lshiftrt:SI (match_operand:SI 1
"immediate_operand" "i")
                                  (const_int 16))))]
  "%0.h = #HI(%1)"

When I try to build, the cross compiler gives the following error:

./crtstuff.c: In function `__do_global_dtors_aux':
./crtstuff.c:261: internal compiler error: in expand_simple_unop, at

Why does this not work?  I think the truncate expression is the problem.
Is this not the way to use truncate?

Thank you,
Charles J. Tabony

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]