This patch adds an alternative to addhi3_zero_extend for the case
where output operand and the 8-bit addend happen to reside
the the same register.  Without the patch this might lead
to additional reloads to satisfy the constraints like


uint16_t func (uint8_t x, uint16_t y)
{
    return x + y;
}


Without the new alternative the code will be


func:
        movw r18,r22     ;  18  *movhi/1        [length = 1]
        add r18,r24      ;  13  *addhi3_zero_extend     [length = 2]
        adc r19,__zero_reg__
        movw r24,r18     ;  19  *movhi/1        [length = 1]
/* epilogue start */
        ret


With the change the code reads


func:
        add r24,r22      ;  13  *addhi3_zero_extend/2   [length = 3]
        mov r25,r23
        adc r25,__zero_reg__
/* epilogue start */
        ret

which has smaller code size and register pressure.

Ok for trunk?

Johann

        * config/avr/avr.md (*addhi3_zero_extend): Add alternative where
        REGNO($0) == REGNO($1).
Index: config/avr/avr.md
===================================================================
--- config/avr/avr.md	(revision 244001)
+++ config/avr/avr.md	(working copy)
@@ -1200,12 +1200,14 @@ (define_expand "add<mode>3"
 
 
 (define_insn "*addhi3_zero_extend"
-  [(set (match_operand:HI 0 "register_operand"                         "=r")
-        (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
-                 (match_operand:HI 2 "register_operand"                 "0")))]
+  [(set (match_operand:HI 0 "register_operand"                         "=r,*?r")
+        (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r  ,0"))
+                 (match_operand:HI 2 "register_operand"                 "0  ,r")))]
   ""
-  "add %A0,%1\;adc %B0,__zero_reg__"
-  [(set_attr "length" "2")
+  "@
+	add %A0,%1\;adc %B0,__zero_reg__
+	add %A0,%A2\;mov %B0,%B2\;adc %B0,__zero_reg__"
+  [(set_attr "length" "2,3")
    (set_attr "cc" "set_n")])
 
 (define_insn "*addhi3_zero_extend1"

Reply via email to