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 "add3"
(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"