aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2014-11-21 14:04:25 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2014-11-21 14:04:25 +0000
commit00e641f13e16cc2e1402b17f43df934014a95cfb (patch)
treed409635e26b1bc8b6198fb7ae5658c346d46ee81 /gcc
parent7697b16f45c592826e6a6a1a3ac2ca7f6db530bc (diff)
downloadgcc-00e641f13e16cc2e1402b17f43df934014a95cfb.zip
gcc-00e641f13e16cc2e1402b17f43df934014a95cfb.tar.gz
gcc-00e641f13e16cc2e1402b17f43df934014a95cfb.tar.bz2
Forward-port from 2014-10-30 4_9-branch r216934 PR target/63633
gcc/ Forward-port from 2014-10-30 4_9-branch r216934 PR target/63633 * 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) (mul<ALL2QA>3, mul<ALL4A>3, <usdiv><ALL1Q>3, <usdiv><ALL2QA>3) (<usdiv><ALL4A>3, round<ALL124QA>3): Fix input operands. * config/avr/avr-dimode.md (add<ALL8>3, sub<ALL8>3) (<ss_addsub><ALL8S>3, <us_addsub><ALL8U>3, cbranch<ALL8>4) (<di_shifts><ALL8>3, <any_extend>mulsidi3): Fix input operands. * config/avr/avr.md (mulqi3_call, mulhi3_call, mulsi3, mulpsi3) (mulu<QIHI>si3, muls<QIHI>si3, mulohisi3, <any_extend>mulhisi3) (usmulhisi3, <any_extend>mulhi3_highpart, mulsqipsi3) (fmul, fmuls, fmulsu): Fix operands. Turn insn into expander as needed. gcc/testsuite/ Forward-port from 2014-10-30 4_9-branch r216934 PR target/63633 * gcc.target/avr/torture/pr63633-ice-mult.c: New test. From-SVN: r217922
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/avr/avr-dimode.md7
-rw-r--r--gcc/config/avr/avr-fixed.md41
-rw-r--r--gcc/config/avr/avr-protos.h9
-rw-r--r--gcc/config/avr/avr.c109
-rw-r--r--gcc/config/avr/avr.md113
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr63633-ice-mult.c37
7 files changed, 307 insertions, 16 deletions
diff --git a/gcc/config/avr/avr-dimode.md b/gcc/config/avr/avr-dimode.md
index 6398105..56cd304 100644
--- a/gcc/config/avr/avr-dimode.md
+++ b/gcc/config/avr/avr-dimode.md
@@ -68,6 +68,7 @@
{
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, ACC_A));
emit_move_insn (acc_a, operands[1]);
if (DImode == <MODE>mode
@@ -145,6 +146,7 @@
{
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, ACC_A));
emit_move_insn (acc_a, operands[1]);
if (const_operand (operands[2], GET_MODE (operands[2])))
@@ -201,6 +203,7 @@
{
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, ACC_A));
emit_move_insn (acc_a, operands[1]);
if (const_operand (operands[2], GET_MODE (operands[2])))
@@ -249,6 +252,7 @@
{
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, ACC_A));
emit_move_insn (acc_a, operands[1]);
if (const_operand (operands[2], GET_MODE (operands[2])))
@@ -338,6 +342,7 @@
{
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, ACC_A));
emit_move_insn (acc_a, operands[1]);
if (s8_operand (operands[2], VOIDmode))
@@ -424,6 +429,7 @@
{
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, ACC_A));
emit_move_insn (acc_a, operands[1]);
emit_move_insn (gen_rtx_REG (QImode, 16), operands[2]);
emit_insn (gen_<code_stdname><mode>3_insn ());
@@ -457,6 +463,7 @@
(clobber (any_extend:SI (match_dup 1)))])]
"avr_have_dimode"
{
+ avr_fix_inputs (operands, 1 << 2, regmask (SImode, 22));
emit_move_insn (gen_rtx_REG (SImode, 22), operands[1]);
emit_move_insn (gen_rtx_REG (SImode, 18), operands[2]);
emit_insn (gen_<extend_u>mulsidi3_insn());
diff --git a/gcc/config/avr/avr-fixed.md b/gcc/config/avr/avr-fixed.md
index 9c8489e..6763f59 100644
--- a/gcc/config/avr/avr-fixed.md
+++ b/gcc/config/avr/avr-fixed.md
@@ -231,7 +231,11 @@
(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 @@
(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 @@
(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 (<MODE>mode, 18));
+ })
;; "*mulhq3.call" "*muluhq3.call"
;; "*mulha3.call" "*muluha3.call"
@@ -302,7 +312,10 @@
(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 (<MODE>mode, 16));
+ })
;; "*mulsa3.call" "*mulusa3.call"
(define_insn "*mul<mode>3.call"
@@ -330,7 +343,12 @@
(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 (<MODE>mode, 25));
+ })
+
;; "*divqq3.call" "*udivuqq3.call"
(define_insn "*<code><mode>3.call"
@@ -356,7 +374,11 @@
(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 (<MODE>mode, 26));
+ })
;; "*divhq3.call" "*udivuhq3.call"
;; "*divha3.call" "*udivuha3.call"
@@ -385,7 +407,11 @@
(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 (<MODE>mode, 24));
+ })
;; "*divsa3.call" "*udivusa3.call"
(define_insn "*<code><mode>3.call"
@@ -435,6 +461,7 @@
operands[3] = gen_rtx_REG (<MODE>mode, regno_out[(size_t) GET_MODE_SIZE (<MODE>mode)]);
operands[4] = gen_rtx_REG (<MODE>mode, regno_in[(size_t) GET_MODE_SIZE (<MODE>mode)]);
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, REGNO (operands[4])));
operands[5] = simplify_gen_subreg (QImode, force_reg (HImode, operands[2]), HImode, 0);
// $2 is no more needed, but is referenced for expand.
operands[2] = const0_rtx;
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h
index 8a0e2bd..bdb7542 100644
--- a/gcc/config/avr/avr-protos.h
+++ b/gcc/config/avr/avr-protos.h
@@ -129,6 +129,15 @@ extern bool avr_load_libgcc_p (rtx);
extern bool avr_xload_libgcc_p (machine_mode);
extern rtx avr_eval_addr_attrib (rtx x);
+static inline unsigned
+regmask (machine_mode mode, unsigned regno)
+{
+ return ((1u << GET_MODE_SIZE (mode)) - 1) << regno;
+}
+
+extern void avr_fix_inputs (rtx*, unsigned, unsigned);
+extern bool avr_emit3_fix_outputs (rtx (*)(rtx,rtx,rtx), rtx*, unsigned, unsigned);
+
extern rtx lpm_reg_rtx;
extern rtx lpm_addr_reg_rtx;
extern rtx tmp_reg_rtx;
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index bbd8644..bc83adb 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -12201,6 +12201,115 @@ avr_convert_to_type (tree type, tree expr)
}
+/* PR63633: The middle-end might come up with hard regs as input operands.
+
+ RMASK is a bit mask representing a subset of hard registers R0...R31:
+ Rn is an element of that set iff bit n of RMASK is set.
+ OPMASK describes a subset of OP[]: If bit n of OPMASK is 1 then
+ OP[n] has to be fixed; otherwise OP[n] is left alone.
+
+ For each element of OPMASK which is a hard register overlapping RMASK,
+ replace OP[n] with a newly created pseudo register
+
+ HREG == 0: Also emit a move insn that copies the contents of that
+ hard register into the new pseudo.
+
+ HREG != 0: Also set HREG[n] to the hard register. */
+
+static void
+avr_fix_operands (rtx *op, rtx *hreg, unsigned opmask, unsigned rmask)
+{
+ for (; opmask; opmask >>= 1, op++)
+ {
+ rtx reg = *op;
+
+ if (hreg)
+ *hreg = NULL_RTX;
+
+ if ((opmask & 1)
+ && REG_P (reg)
+ && REGNO (reg) < FIRST_PSEUDO_REGISTER
+ // This hard-reg overlaps other prohibited hard regs?
+ && (rmask & regmask (GET_MODE (reg), REGNO (reg))))
+ {
+ *op = gen_reg_rtx (GET_MODE (reg));
+ if (hreg == NULL)
+ emit_move_insn (*op, reg);
+ else
+ *hreg = reg;
+ }
+
+ if (hreg)
+ hreg++;
+ }
+}
+
+
+void
+avr_fix_inputs (rtx *op, unsigned opmask, unsigned rmask)
+{
+ avr_fix_operands (op, NULL, opmask, rmask);
+}
+
+
+/* Helper for the function below: If bit n of MASK is set and
+ HREG[n] != NULL, then emit a move insn to copy OP[n] to HREG[n].
+ Otherwise do nothing for that n. Return TRUE. */
+
+static bool
+avr_move_fixed_operands (rtx *op, rtx *hreg, unsigned mask)
+{
+ for (; mask; mask >>= 1, op++, hreg++)
+ if ((mask & 1)
+ && *hreg)
+ emit_move_insn (*hreg, *op);
+
+ return true;
+}
+
+
+/* PR63633: The middle-end might come up with hard regs as output operands.
+
+ GEN is a sequence generating function like gen_mulsi3 with 3 operands OP[].
+ RMASK is a bit mask representing a subset of hard registers R0...R31:
+ Rn is an element of that set iff bit n of RMASK is set.
+ OPMASK describes a subset of OP[]: If bit n of OPMASK is 1 then
+ OP[n] has to be fixed; otherwise OP[n] is left alone.
+
+ Emit the insn sequence as generated by GEN() with all elements of OPMASK
+ which are hard registers overlapping RMASK replaced by newly created
+ pseudo registers. After the sequence has been emitted, emit insns that
+ move the contents of respective pseudos to their hard regs. */
+
+bool
+avr_emit3_fix_outputs (rtx (*gen)(rtx,rtx,rtx), rtx *op,
+ unsigned opmask, unsigned rmask)
+{
+ const int n = 3;
+ rtx hreg[n];
+
+ /* It is letigimate for GEN to call this function, and in order not to
+ get self-recursive we use the following static kludge. This is the
+ only way not to duplicate all expanders and to avoid ugly and
+ hard-to-maintain C-code instead of the much more appreciated RTL
+ representation as supplied by define_expand. */
+ static bool lock = false;
+
+ gcc_assert (opmask < (1u << n));
+
+ if (lock)
+ return false;
+
+ avr_fix_operands (op, hreg, opmask, rmask);
+
+ lock = true;
+ emit_insn (gen (op[0], op[1], op[2]));
+ lock = false;
+
+ return avr_move_fixed_operands (op, hreg, opmask);
+}
+
+
/* Worker function for movmemhi expander.
XOP[0] Destination as MEM:BLK
XOP[1] Source " "
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index a2c3872..9f722cb 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -1548,7 +1548,11 @@
(set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
(parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
(clobber (reg:QI 22))])
- (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))])
+ (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
+ ""
+ {
+ avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
+ })
(define_insn "*mulqi3_call"
[(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
@@ -2276,7 +2280,13 @@
(parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
(clobber (reg:HI 22))
(clobber (reg:QI 21))])
- (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))])
+ (set (match_operand:HI 0 "register_operand" "")
+ (reg:HI 24))]
+ ""
+ {
+ avr_fix_inputs (operands, (1 << 2), regmask (HImode, 24));
+ })
+
(define_insn "*mulhi3_call"
[(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
@@ -2314,6 +2324,10 @@
emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
DONE;
}
+
+ if (avr_emit3_fix_outputs (gen_mulsi3, operands, 1 << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
})
(define_insn_and_split "*mulsi3"
@@ -2353,7 +2367,23 @@
;; "muluqisi3"
;; "muluhisi3"
-(define_insn_and_split "mulu<mode>si3"
+(define_expand "mulu<mode>si3"
+ [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
+ (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" ""))
+ (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
+ (clobber (reg:HI 26))
+ (clobber (reg:DI 18))])]
+ "AVR_HAVE_MUL"
+ {
+ avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
+ if (avr_emit3_fix_outputs (gen_mulu<mode>si3, operands, 1 << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
+ })
+
+;; "*muluqisi3"
+;; "*muluhisi3"
+(define_insn_and_split "*mulu<mode>si3"
[(set (match_operand:SI 0 "pseudo_register_operand" "=r")
(mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
(match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
@@ -2389,7 +2419,23 @@
;; "mulsqisi3"
;; "mulshisi3"
-(define_insn_and_split "muls<mode>si3"
+(define_expand "muls<mode>si3"
+ [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
+ (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" ""))
+ (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
+ (clobber (reg:HI 26))
+ (clobber (reg:DI 18))])]
+ "AVR_HAVE_MUL"
+ {
+ avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
+ if (avr_emit3_fix_outputs (gen_muls<mode>si3, operands, 1 << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
+ })
+
+;; "*mulsqisi3"
+;; "*mulshisi3"
+(define_insn_and_split "*muls<mode>si3"
[(set (match_operand:SI 0 "pseudo_register_operand" "=r")
(mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
(match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
@@ -2432,7 +2478,22 @@
;; One-extend operand 1
-(define_insn_and_split "mulohisi3"
+(define_expand "mulohisi3"
+ [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
+ (mult:SI (not:SI (zero_extend:SI
+ (not:HI (match_operand:HI 1 "pseudo_register_operand" ""))))
+ (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
+ (clobber (reg:HI 26))
+ (clobber (reg:DI 18))])]
+ "AVR_HAVE_MUL"
+ {
+ avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
+ if (avr_emit3_fix_outputs (gen_mulohisi3, operands, 1 << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
+ })
+
+(define_insn_and_split "*mulohisi3"
[(set (match_operand:SI 0 "pseudo_register_operand" "=r")
(mult:SI (not:SI (zero_extend:SI
(not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
@@ -2460,7 +2521,12 @@
(any_extend:SI (match_operand:HI 2 "register_operand" ""))))
(clobber (reg:HI 26))
(clobber (reg:DI 18))])]
- "AVR_HAVE_MUL")
+ "AVR_HAVE_MUL"
+ {
+ if (avr_emit3_fix_outputs (gen_<extend_u>mulhisi3, operands, 1 << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
+ })
(define_expand "usmulhisi3"
[(parallel [(set (match_operand:SI 0 "register_operand" "")
@@ -2468,7 +2534,12 @@
(sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
(clobber (reg:HI 26))
(clobber (reg:DI 18))])]
- "AVR_HAVE_MUL")
+ "AVR_HAVE_MUL"
+ {
+ if (avr_emit3_fix_outputs (gen_usmulhisi3, operands, 1 << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
+ })
;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
@@ -2540,7 +2611,10 @@
(clobber (reg:HI 22))])
(set (match_operand:HI 0 "register_operand" "")
(reg:HI 24))]
- "AVR_HAVE_MUL")
+ "AVR_HAVE_MUL"
+ {
+ avr_fix_inputs (operands, 1 << 2, regmask (HImode, 18));
+ })
(define_insn "*mulsi3_call"
@@ -2763,6 +2837,10 @@
emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
DONE;
}
+
+ if (avr_emit3_fix_outputs (gen_mulpsi3, operands, 1u << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
})
(define_insn "*umulqihipsi3"
@@ -2795,7 +2873,21 @@
[(set_attr "length" "7")
(set_attr "cc" "clobber")])
-(define_insn_and_split "mulsqipsi3"
+(define_expand "mulsqipsi3"
+ [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
+ (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" ""))
+ (match_operand:PSI 2 "pseudo_register_or_const_int_operand""")))
+ (clobber (reg:HI 26))
+ (clobber (reg:DI 18))])]
+ "AVR_HAVE_MUL"
+ {
+ avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
+ if (avr_emit3_fix_outputs (gen_mulsqipsi3, operands, 1 << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
+ })
+
+(define_insn_and_split "*mulsqipsi3"
[(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
(mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
(match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
@@ -6134,6 +6226,7 @@
emit_insn (gen_fmul_insn (operand0, operand1, operand2));
DONE;
}
+ avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
})
(define_insn "fmul_insn"
@@ -6177,6 +6270,7 @@
emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
DONE;
}
+ avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
})
(define_insn "fmuls_insn"
@@ -6220,6 +6314,7 @@
emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
DONE;
}
+ avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
})
(define_insn "fmulsu_insn"
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 55817df..0885198 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2014-11-21 Georg-Johann Lay <avr@gjlay.de>
+
+ Forward-port from 2014-10-30 4_9-branch r216934
+
+ PR target/63633
+ * gcc.target/avr/torture/pr63633-ice-mult.c: New test.
+
2014-11-21 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR debug/63239
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr63633-ice-mult.c b/gcc/testsuite/gcc.target/avr/torture/pr63633-ice-mult.c
new file mode 100644
index 0000000..a523424
--- /dev/null
+++ b/gcc/testsuite/gcc.target/avr/torture/pr63633-ice-mult.c
@@ -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));
+}