On 04/19/2011 02:52 AM, Denis Chertykov wrote: > 2011/4/19 Georg-Johann Lay <a...@gjlay.de>: >> How can add, sub etc. be split? This would need an explicit >> representation of carry. > > Yes. > > Look at http://gcc.gnu.org/ml/gcc/2005-03/msg00871.html
Well, sort-of, but not really. It gets a tad ugly, but have a look at the adddi3* patterns in the mn10300 and rx ports. In particular note how both the inputs and outputs to the insn (not the expander) are all SImode, allowing for lower_subreg to do its job. The patterns are split post-reload -- some of that is for scheduling, some of that simply makes computing the individual insn lengths significantly easier -- but you wouldn't really have to do that for AVR. For AVR things would become even trickier. You might consider (define_predicate "concat_operator" (match_code "concat")) (define_insn "addsi3_qqqq" [(set (match_operand:QI 0 "register_operand" "=r") (truncate:QI (plus:SI (match_operator:SI 12 "concat_operator" [(match_operand:QI 4 "register_operand" "0") (match_operand:QI 5 "register_operand" "1") (match_operand:QI 6 "register_operand" "2") (match_operand:QI 7 "register_operand" "3")]) (match_operator:SI 13 "concat_operator" [(match_operand:QI 8 "reg_or_0_operand" "rL") (match_operand:QI 9 "reg_or_0_operand" "rL") (match_operand:QI 10 "reg_or_0_operand" "rL") (match_operand:QI 11 "reg_or_0_operand" "rL")]))) (set (match_operand:QI 1 "register_operand" "=r") (truncate:QI (lshiftrt:SI (plus:SI (match_dup 24) (match_dup 25)) (const_int 8)))) (set (match_operand:QI 2 "register_operand" "=r") (truncate:QI (lshiftrt:SI (plus:SI (match_dup 24) (match_dup 25)) (const_int 16)))) (set (match_operand:QI 3 "register_operand" "=r") (truncate:QI (lshiftrt:SI (plus:SI (match_dup 24) (match_dup 25)) (const_int 24))))] "" "add %0,%Z8\;adc %1,%Z9\;adc %2,%Z10\;adc %3,%Z11" [(set_attr "length" "4")] ) This may require a little bit of code inside combine to handle CONCAT in a reasonable way, but that should be fairly minimal. It may also want some more special case patterns and/or peep2s to more efficiently handle constants, particularly considering adiw and subic. But I think it's at least worth investigating. r~