mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-22 19:11:18 +08:00
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
This commit is contained in:
parent
7697b16f45
commit
00e641f13e
gcc
config/avr
testsuite
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 " "
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
37
gcc/testsuite/gcc.target/avr/torture/pr63633-ice-mult.c
Normal file
37
gcc/testsuite/gcc.target/avr/torture/pr63633-ice-mult.c
Normal file
@ -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));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user