This is the mail archive of the gcc-patches@gcc.gnu.org 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]

Re: [Patch,AVR]: FIX ICE in optabs due to bad rotate expander.


On 04/19/2011 02:52 AM, Denis Chertykov wrote:
> 2011/4/19 Georg-Johann Lay <avr@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~


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