On 01/29/2015 02:08 AM, Paul Shortis wrote: > I've ported GCC to a small 16 bit CPU that has single bit shifts. So I've > handled variable / multi-bit shifts using a mix of inline shifts and calls to > assembler support functions. > > The calls to the asm library functions clobber only one (by const) or two > (variable) registers but of course calling these functions causes all of the > standard call clobbered registers to be considered clobbered, thus wasting > lots > of candidate registers for use in expressions surrounding these shifts and > causing unnecessary register saves in the surrounding function > prologue/epilogue. > > I've scrutinized and cloned the actions of other ports that do the same, > however I'm unable to convince the various passes that only r1 and r2 can be > clobbered by these library calls. > > Is anyone able to point me in the proper direction for a solution to this > problem ?
You wind up writing a pattern that contains a call, but isn't represented in rtl as a call. The SH port does this for its shifts too. See (define_expand "ashlsi3" [(set (match_operand:SI 0 "arith_reg_operand" "") (ashift:SI (match_operand:SI 1 "arith_reg_operand" "") (match_operand:SI 2 "shift_count_operand" "")))] ... /* Expand a library call for the dynamic shift. */ if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT) { emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]); rtx funcaddr = gen_reg_rtx (Pmode); function_symbol (funcaddr, "__ashlsi3_r0", SFUNC_STATIC); emit_insn (gen_ashlsi3_d_call (operands[0], operands[2], funcaddr)); DONE; } }) ... ;; If dynamic shifts are not available use a library function. ;; By specifying the pattern we reduce the number of call clobbered regs. ;; In order to make combine understand the truncation of the shift amount ;; operand we have to allow it to use pseudo regs for the shift operands. (define_insn "ashlsi3_d_call" [(set (match_operand:SI 0 "arith_reg_dest" "=z") (ashift:SI (reg:SI R4_REG) (and:SI (match_operand:SI 1 "arith_reg_operand" "z") (const_int 31)))) (use (match_operand:SI 2 "arith_reg_operand" "r")) (clobber (reg:SI T_REG)) (clobber (reg:SI PR_REG))] "TARGET_SH1 && !TARGET_DYNSHIFT" "jsr @%2%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")]) r~