On Fri, Oct 12, 2012 at 8:04 AM, Tomasz Jankowski <tomcioj@xxxxxxxxx> wrote: > > I'm working on machine description for modified OpenRISC and at the > moment I'm trying to modify standard "addsi3" insn. I have custom add > in instruction called "radd", which I'm going to use for regular > arithmetic (for computing addresses, offsets for stack pointer etc. I > use "standard" OpenRISC instructions). The problem with "radd" is only > operates on register, so when I have to add immediate to register I > have to first manually copy immediate to temporary register and then > call my "radd" instruction. I implemented code for that: > > > > (define_expand "addsi3" > [(set (match_operand:SI 0 "general_operand" "") > (plus:SI (match_operand:SI 1 "general_operand" "") > (match_operand:SI 2 "general_operand" "")))] > "" > { > if (CONST_INT_P (operands [2])) > { > operands [2] = force_reg (SImode, operands [2]); > emit_insn (gen_rto (operands [2], operands [2])); > } > > //emit_insn (gen_rtx_SET (VOIDmode, operands [0], gen_rtx_PLUS > (SImode, operands [1], operands [2]))); > DONE; > }) > > (define_insn "radd" > [(set (match_operand:SI 0 "register_operand" "=r") > (plus:SI (match_operand:SI 1 "register_operand" "%r") > (match_operand:SI 2 "register_operand" "r")))] > "" > "l.radd \t%0,%1,%2" > [(set_attr "type" "add") > (set_attr "length" "1")]) > > > > During GCC compilation, when self test are run GCC fails on assertion: > > gcc_assert (can_create_pseudo_p ()); > > in function: > > rtx gen_reg_rtx (enum machine_mode mode) > > Why I cannot create temporary registers in define_expand? What's > possible workaround for this issue? Most likely the reload pass has decided that it needs to add a constant to a register, most likely because it needs to refer to a stack slot. In such a case, can_create_pseudo_p will return false. You could look higher on the stack to see precisely why this is happening. But most likely you are going to have to support addsi3 with a constant integer when you can't allocate a new pseudo register. The usual way to handle this is to emit two instructions in this case: one to load the constant into the destination register, one to add the other source register to the destination register. Ian