Middle-end might come up with hard registers as operands for expanders which
clobber respective hard regs. This patch uses freshly created pseudos for
respective expander operands and emits pseudo - hard move insn.
Ok for 4.9.2?
It's not yet for trunk because avr trunk backend is currently broken.
Johann
gcc/
PR63633
* config/avr/avr-protos.h (regmask): New inline function.
(avr_fix_inputs, avr_emit3_fix_outputs): New protos.
* config/avr/avr.c (avr_fix_operands, avr_move_fixed_operands)
(avr_fix_inputs, avr_emit3_fix_outputs): New functions.
* config/avr/avr-fixed.md (mulqq3_nomul, muluqq3_nomul)
(mulALL2QA3, mulALL4A3, usdivALL1Q3, usdivALL2QA3)
(usdivALL4A3, roundALL124QA3): Fix input operands.
* config/avr/avr-dimode.md (addALL83, subALL83)
(ss_addsubALL8S3, us_addsubALL8U3, cbranchALL84)
(di_shiftsALL83, any_extendmulsidi3): Fix input operands.
* config/avr/avr.md (mulqi3_call, mulhi3_call, mulsi3, mulpsi3)
(muluQIHIsi3, mulsQIHIsi3, mulohisi3, any_extendmulhisi3)
(usmulhisi3, any_extendmulhi3_highpart, mulsqipsi3)
(fmul, fmuls, fmulsu): Fix operands. Turn insn into expander as
needed.
gcc/testsuite/
PR63633
* gcc.target/avr/torture/pr63633-ice-mult.c: New test.
Index: testsuite/gcc.target/avr/torture/pr63633-ice-mult.c
===
--- testsuite/gcc.target/avr/torture/pr63633-ice-mult.c (revision 0)
+++ testsuite/gcc.target/avr/torture/pr63633-ice-mult.c (revision 0)
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+
+void ice_mult32 (int x)
+{
+ register long reg __asm (22);
+ __asm volatile ( :: r (reg = 0x12345 * x));
+}
+
+void ice_mult24 (int x)
+{
+ register __int24 reg __asm (20);
+ __asm volatile ( :: r (reg = 0x12345 * x));
+}
+
+void ice_sh24 (__int24 x)
+{
+ register __int24 reg __asm (20);
+ __asm volatile ( :: r (reg = x 3));
+}
+
+void ice_sh24b (__int24 x)
+{
+ register __int24 reg __asm (20);
+ __asm volatile ( :: r (reg = x 22));
+}
+
+void ice_s16s16 (int x)
+{
+ register long reg __asm (20);
+ __asm volatile ( :: r (reg = (long) x*x));
+}
+
+void ice_u16s16 (int x)
+{
+ register long reg __asm (20);
+ __asm volatile ( :: r (reg = (long) x*0x1234u));
+}
Index: config/avr/avr-fixed.md
===
--- config/avr/avr-fixed.md (revision 215212)
+++ config/avr/avr-fixed.md (working copy)
@@ -231,7 +231,11 @@ (define_expand mulqq3_nomul
(clobber (reg:HI 24))])
(set (match_operand:QQ 0 register_operand )
(reg:QQ 23))]
- !AVR_HAVE_MUL)
+ !AVR_HAVE_MUL
+ {
+avr_fix_inputs (operands, 1 2, regmask (QQmode, 24));
+ })
+
(define_expand muluqq3_nomul
[(set (reg:UQQ 22)
@@ -246,7 +250,10 @@ (define_expand muluqq3_nomul
(clobber (reg:HI 22))])
(set (match_operand:UQQ 0 register_operand )
(reg:UQQ 25))]
- !AVR_HAVE_MUL)
+ !AVR_HAVE_MUL
+ {
+avr_fix_inputs (operands, 1 2, regmask (UQQmode, 22));
+ })
(define_insn *mulqq3.call
[(set (reg:QQ 23)
@@ -274,7 +281,10 @@ (define_expand mulmode3
(clobber (reg:HI 22))])
(set (match_operand:ALL2QA 0 register_operand )
(reg:ALL2QA 24))]
- AVR_HAVE_MUL)
+ AVR_HAVE_MUL
+ {
+avr_fix_inputs (operands, 1 2, regmask (MODEmode, 18));
+ })
;; *mulhq3.call *muluhq3.call
;; *mulha3.call *muluha3.call
@@ -302,7 +312,10 @@ (define_expand mulmode3
(reg:ALL4A 20)))
(set (match_operand:ALL4A 0 register_operand )
(reg:ALL4A 24))]
- AVR_HAVE_MUL)
+ AVR_HAVE_MUL
+ {
+avr_fix_inputs (operands, 1 2, regmask (MODEmode, 16));
+ })
;; *mulsa3.call *mulusa3.call
(define_insn *mulmode3.call
@@ -330,7 +343,12 @@ (define_expand codemode3
(reg:ALL1Q 22)))
(clobber (reg:QI 25))])
(set (match_operand:ALL1Q 0 register_operand )
-(reg:ALL1Q 24))])
+(reg:ALL1Q 24))]
+
+ {
+avr_fix_inputs (operands, 1 2, regmask (MODEmode, 25));
+ })
+
;; *divqq3.call *udivuqq3.call
(define_insn *codemode3.call
@@ -356,7 +374,11 @@ (define_expand codemode3
(clobber (reg:HI 26))
(clobber (reg:QI 21))])
(set (match_operand:ALL2QA 0 register_operand )
-(reg:ALL2QA 24))])
+(reg:ALL2QA 24))]
+
+ {
+avr_fix_inputs (operands, 1 2, regmask (MODEmode, 26));
+ })
;; *divhq3.call *udivuhq3.call
;; *divha3.call *udivuha3.call
@@ -385,7 +407,11 @@ (define_expand codemode3
(clobber (reg:HI 26))
(clobber (reg:HI 30))])
(set (match_operand:ALL4A 0 register_operand )
-(reg:ALL4A 22))])
+(reg:ALL4A 22))]
+
+ {
+avr_fix_inputs (operands, 1 2, regmask (MODEmode, 24));
+ })
;; *divsa3.call *udivusa3.call
(define_insn *codemode3.call
@@ -435,6 +461,7 @@ (define_expand roundmode3