md.texi: Synchronize with later constraints.md change.
gcc/ * doc/md.texi: Synchronize with later constraints.md change. * longlong.h (umul_ppmm): Replace the MIPS asm implementation with a C implementation. * config/mips/mips.c (mips_legitimize_move): Remove MFHI and MFLO handling. (mips_subword): Assume TImode for CONST_INTs if TARGET_64BIT. (mips_split_doubleword_move): Use special MTHI and MFHI instructions when moving to and from MD_REGNUM. (mips_output_move): Don't handle moves from GPRs to HI_REGNUM. Handle moves from LO_REGNUM to GPRs using MFLO, MACC or DMACC. Handle byte and halfword moves. (mips_hard_regno_mode_ok_p): Handle MD_REGS and DSP_ACC_REGS separately. * config/mips/constraints.md (h): Turn into NO_REGS. (l, x): Update documentation. * config/mips/mips.md (UNSPEC_MFHILO): Delete. (UNSPEC_MFHI, UNSPEC_MTHI, UNSPEC_SET_HILO): New. (UNSPEC_TLS_LDM, UNSPEC_TLS_GET_TP): Renumber. (HILO): New mode iterator. (MOVE128): Add TI. (any_div): New code iterator. (u): Extend code attribute to div and udiv. (*add<mode>3_mips16, *movdi_64bit_mips16, *movsi_mips16): Use d_operand in the splitters. Remove redundant CONST_INT checks. (mulsi3_mult3, mul<mode>3_internal, mul<mode>3_r4000, *mul_acc_si) (*macc, *msac, *msac_using_macc, *macc2, *msac2, *mul_sub_si) (*muls): Remove "=h" clobbers. Adjust peephole2s and define_splits accordingly, using normal moves instead of unspecs to move LO into a GPR. Use d_operand and lo_operand instead of *_REG_P checks. (<u>mulsidi3): Handle expansion in C code. (<u>mulsidi3_32bit_internal): Rename to... (<u>mulsidi3_32bit): ...this. (<u>mulsidi3_32bit_r4000): Fix insn separator. (*<u>mulsidi3_64bit): Rename to... (<u>mulsidi3_64bit): ...this. Combine DImode "=h" and "=l" clobbers into a TImode "=x" clobber. In the split, use an UNSPEC_SET_HILO to set LO and HI to the multiplication result. Use a normal move for MFLO and an unspec for MFHI. (*<u>mulsidi3_64bit_parts): Replace with... (<u>mulsidi3_64bit_hilo): ...this new instruction. (<su>mulsi3_highpart): Extend to TARGET_FIX_R4000. (<su>mulsi3_highpart_internal): Turn into a define_insn_and_split and extend it to TARGET_FIX_R4000. Store the destination in a GPR instead of HI. Split the instruction into a separate multiplication and MFHI if !TARGET_FIX_R4000. (<su>muldi3_highpart): Likewise. (<su>mulsi3_highpart_mulhi_internal): Remove the first alternative and the "=h" clobber. (*<su>mulsi3_highpart_neg_mulhi_internal): Likewise. (<u>mulditi3): New expander. (<u>mulditi3_internal, <u>mulditi3_r4000): New patterns. (madsi): Remove "=h" clobber. (divmod<mode>4, udivmod<mode>4): Turn into define_insn_and_splits. Force the modulus result to be a GPR and split the instruction into a division followed by an MFHI after reload. (<u>divmod<GPR:mode>4_hilo_<HILO:mode>): New instruction. (*lea_high64): Use d_operand in the define_peephole2. Likewise the MIPS16 HIGH define_split. (*movdi_32bit, *movdi_gp32_fp64, *movdi_32bit_mips16): Change type of acc<->gpr moves to "multi". (*movdi_64bit): Replace the single "x" alternative with alternatives for moving into and out of "a". (*movhi_internal, *movqi_internal): Likewise. Use mips_output_move. (*movsi_internal): Extend the "d<-A" alternative to "d<-a". (*movdi_64bit_mips16, *movsi_mips16): Add d<-a alternatives. Use d_operand in the splitters. Remove redundant CONST_INT checks. (*movhi_mips16, *movqi_mips16): Likewise. Use mips_output_move. (movti): New expander. (*movti, *movti_mips16): New insns. (mfhilo_<mode>, *mfhilo_<mode>, *mfhilo_<mode>_macc): Delete. (mfhi<GPR:mode>_<HILO:mode>): New pattern. (mthi<GPR:mode>_<HILO:mode>): Likewise. * config/mips/predicates.md (fpr_operand): Delete. (d_operand): New predicate. gcc/testsuite/ * gcc.dg/torture/mips-hilo-1.c: Delete. * gcc.target/mips/pr35232.c: Likewise. * gcc.target/mips/fix-vr4130-1.c: Use modulus to create an mfhi. * gcc.target/mips/fix-vr4130-3.c: Likewise. * gcc.target/mips/int-moves-1.c: New test. * gcc.target/mips/int-moves-2.c: Likewise. * gcc.target/mips/fix-r4000-1.c: Likewise. * gcc.target/mips/fix-r4000-2.c: Likewise. * gcc.target/mips/fix-r4000-3.c: Likewise. * gcc.target/mips/fix-r4000-4.c: Likewise. * gcc.target/mips/fix-r4000-5.c: Likewise. * gcc.target/mips/fix-r4000-6.c: Likewise. * gcc.target/mips/fix-r4000-7.c: Likewise. * gcc.target/mips/fix-r4000-8.c: Likewise. * gcc.target/mips/fix-r4000-9.c: Likewise. * gcc.target/mips/fix-r4000-10.c: Likewise. * gcc.target/mips/fix-r4000-11.c: Likewise. * gcc.target/mips/fix-r4000-12.c: Likewise. * gcc.target/mips/timode-1.c: Likewise. * gcc.target/mips/timode-2.c: Likewise. From-SVN: r136600
This commit is contained in:
parent
0e462a951b
commit
21dfc6dc74
|
@ -1,3 +1,80 @@
|
|||
2008-06-09 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* doc/md.texi: Synchronize with later constraints.md change.
|
||||
* longlong.h (umul_ppmm): Replace the MIPS asm implementation
|
||||
with a C implementation.
|
||||
* config/mips/mips.c (mips_legitimize_move): Remove MFHI and
|
||||
MFLO handling.
|
||||
(mips_subword): Assume TImode for CONST_INTs if TARGET_64BIT.
|
||||
(mips_split_doubleword_move): Use special MTHI and MFHI instructions
|
||||
when moving to and from MD_REGNUM.
|
||||
(mips_output_move): Don't handle moves from GPRs to HI_REGNUM.
|
||||
Handle moves from LO_REGNUM to GPRs using MFLO, MACC or DMACC.
|
||||
Handle byte and halfword moves.
|
||||
(mips_hard_regno_mode_ok_p): Handle MD_REGS and DSP_ACC_REGS
|
||||
separately.
|
||||
* config/mips/constraints.md (h): Turn into NO_REGS.
|
||||
(l, x): Update documentation.
|
||||
* config/mips/mips.md (UNSPEC_MFHILO): Delete.
|
||||
(UNSPEC_MFHI, UNSPEC_MTHI, UNSPEC_SET_HILO): New.
|
||||
(UNSPEC_TLS_LDM, UNSPEC_TLS_GET_TP): Renumber.
|
||||
(HILO): New mode iterator.
|
||||
(MOVE128): Add TI.
|
||||
(any_div): New code iterator.
|
||||
(u): Extend code attribute to div and udiv.
|
||||
(*add<mode>3_mips16, *movdi_64bit_mips16, *movsi_mips16): Use
|
||||
d_operand in the splitters. Remove redundant CONST_INT checks.
|
||||
(mulsi3_mult3, mul<mode>3_internal, mul<mode>3_r4000, *mul_acc_si)
|
||||
(*macc, *msac, *msac_using_macc, *macc2, *msac2, *mul_sub_si)
|
||||
(*muls): Remove "=h" clobbers. Adjust peephole2s and define_splits
|
||||
accordingly, using normal moves instead of unspecs to move LO into
|
||||
a GPR. Use d_operand and lo_operand instead of *_REG_P checks.
|
||||
(<u>mulsidi3): Handle expansion in C code.
|
||||
(<u>mulsidi3_32bit_internal): Rename to...
|
||||
(<u>mulsidi3_32bit): ...this.
|
||||
(<u>mulsidi3_32bit_r4000): Fix insn separator.
|
||||
(*<u>mulsidi3_64bit): Rename to...
|
||||
(<u>mulsidi3_64bit): ...this. Combine DImode "=h" and "=l" clobbers
|
||||
into a TImode "=x" clobber. In the split, use an UNSPEC_SET_HILO
|
||||
to set LO and HI to the multiplication result. Use a normal move
|
||||
for MFLO and an unspec for MFHI.
|
||||
(*<u>mulsidi3_64bit_parts): Replace with...
|
||||
(<u>mulsidi3_64bit_hilo): ...this new instruction.
|
||||
(<su>mulsi3_highpart): Extend to TARGET_FIX_R4000.
|
||||
(<su>mulsi3_highpart_internal): Turn into a define_insn_and_split
|
||||
and extend it to TARGET_FIX_R4000. Store the destination in a GPR
|
||||
instead of HI. Split the instruction into a separate multiplication
|
||||
and MFHI if !TARGET_FIX_R4000.
|
||||
(<su>muldi3_highpart): Likewise.
|
||||
(<su>mulsi3_highpart_mulhi_internal): Remove the first alternative
|
||||
and the "=h" clobber.
|
||||
(*<su>mulsi3_highpart_neg_mulhi_internal): Likewise.
|
||||
(<u>mulditi3): New expander.
|
||||
(<u>mulditi3_internal, <u>mulditi3_r4000): New patterns.
|
||||
(madsi): Remove "=h" clobber.
|
||||
(divmod<mode>4, udivmod<mode>4): Turn into define_insn_and_splits.
|
||||
Force the modulus result to be a GPR and split the instruction into
|
||||
a division followed by an MFHI after reload.
|
||||
(<u>divmod<GPR:mode>4_hilo_<HILO:mode>): New instruction.
|
||||
(*lea_high64): Use d_operand in the define_peephole2. Likewise
|
||||
the MIPS16 HIGH define_split.
|
||||
(*movdi_32bit, *movdi_gp32_fp64, *movdi_32bit_mips16): Change type
|
||||
of acc<->gpr moves to "multi".
|
||||
(*movdi_64bit): Replace the single "x" alternative with
|
||||
alternatives for moving into and out of "a".
|
||||
(*movhi_internal, *movqi_internal): Likewise. Use mips_output_move.
|
||||
(*movsi_internal): Extend the "d<-A" alternative to "d<-a".
|
||||
(*movdi_64bit_mips16, *movsi_mips16): Add d<-a alternatives.
|
||||
Use d_operand in the splitters. Remove redundant CONST_INT checks.
|
||||
(*movhi_mips16, *movqi_mips16): Likewise. Use mips_output_move.
|
||||
(movti): New expander.
|
||||
(*movti, *movti_mips16): New insns.
|
||||
(mfhilo_<mode>, *mfhilo_<mode>, *mfhilo_<mode>_macc): Delete.
|
||||
(mfhi<GPR:mode>_<HILO:mode>): New pattern.
|
||||
(mthi<GPR:mode>_<HILO:mode>): Likewise.
|
||||
* config/mips/predicates.md (fpr_operand): Delete.
|
||||
(d_operand): New predicate.
|
||||
|
||||
2008-06-09 Michael Meissner <michael.meissner@amd.com>
|
||||
|
||||
* config.gcc (i[34567]86-*-*): Put test in quotes to prevent
|
||||
|
|
|
@ -29,14 +29,16 @@
|
|||
(define_register_constraint "f" "TARGET_HARD_FLOAT ? FP_REGS : NO_REGS"
|
||||
"A floating-point register (if available).")
|
||||
|
||||
(define_register_constraint "h" "TARGET_BIG_ENDIAN ? MD0_REG : MD1_REG"
|
||||
"The @code{hi} register.")
|
||||
(define_register_constraint "h" "NO_REGS"
|
||||
"Formerly the @code{hi} register. This constraint is no longer supported.")
|
||||
|
||||
(define_register_constraint "l" "TARGET_BIG_ENDIAN ? MD1_REG : MD0_REG"
|
||||
"The @code{lo} register.")
|
||||
"The @code{lo} register. Use this register to store values that are
|
||||
no bigger than a word.")
|
||||
|
||||
(define_register_constraint "x" "MD_REGS"
|
||||
"The @code{hi} and @code{lo} registers.")
|
||||
"The concatenated @code{hi} and @code{lo} registers. Use this register
|
||||
to store doubleword values.")
|
||||
|
||||
(define_register_constraint "b" "ALL_REGS"
|
||||
"@internal")
|
||||
|
|
|
@ -2675,23 +2675,6 @@ mips_legitimize_move (enum machine_mode mode, rtx dest, rtx src)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Check for individual, fully-reloaded mflo and mfhi instructions. */
|
||||
if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
|
||||
&& REG_P (src) && MD_REG_P (REGNO (src))
|
||||
&& REG_P (dest) && GP_REG_P (REGNO (dest)))
|
||||
{
|
||||
int other_regno = REGNO (src) == HI_REGNUM ? LO_REGNUM : HI_REGNUM;
|
||||
if (GET_MODE_SIZE (mode) <= 4)
|
||||
emit_insn (gen_mfhilo_si (gen_lowpart (SImode, dest),
|
||||
gen_lowpart (SImode, src),
|
||||
gen_rtx_REG (SImode, other_regno)));
|
||||
else
|
||||
emit_insn (gen_mfhilo_di (gen_lowpart (DImode, dest),
|
||||
gen_lowpart (DImode, src),
|
||||
gen_rtx_REG (DImode, other_regno)));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* We need to deal with constants that would be legitimate
|
||||
immediate_operands but aren't legitimate move_operands. */
|
||||
if (CONSTANT_P (src) && !move_operand (src, mode))
|
||||
|
@ -3488,7 +3471,7 @@ mips_subword (rtx op, bool high_p)
|
|||
|
||||
mode = GET_MODE (op);
|
||||
if (mode == VOIDmode)
|
||||
mode = DImode;
|
||||
mode = TARGET_64BIT ? TImode : DImode;
|
||||
|
||||
if (TARGET_BIG_ENDIAN ? !high_p : high_p)
|
||||
byte = UNITS_PER_WORD;
|
||||
|
@ -3539,6 +3522,8 @@ mips_split_64bit_move_p (rtx dest, rtx src)
|
|||
void
|
||||
mips_split_doubleword_move (rtx dest, rtx src)
|
||||
{
|
||||
rtx low_dest;
|
||||
|
||||
if (FP_REG_RTX_P (dest) || FP_REG_RTX_P (src))
|
||||
{
|
||||
if (!TARGET_64BIT && GET_MODE (dest) == DImode)
|
||||
|
@ -3552,12 +3537,27 @@ mips_split_doubleword_move (rtx dest, rtx src)
|
|||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else if (REG_P (dest) && REGNO (dest) == MD_REG_FIRST)
|
||||
{
|
||||
low_dest = mips_subword (dest, false);
|
||||
mips_emit_move (low_dest, mips_subword (src, false));
|
||||
if (TARGET_64BIT)
|
||||
emit_insn (gen_mthidi_ti (dest, mips_subword (src, true), low_dest));
|
||||
else
|
||||
emit_insn (gen_mthisi_di (dest, mips_subword (src, true), low_dest));
|
||||
}
|
||||
else if (REG_P (src) && REGNO (src) == MD_REG_FIRST)
|
||||
{
|
||||
mips_emit_move (mips_subword (dest, false), mips_subword (src, false));
|
||||
if (TARGET_64BIT)
|
||||
emit_insn (gen_mfhidi_ti (mips_subword (dest, true), src));
|
||||
else
|
||||
emit_insn (gen_mfhisi_di (mips_subword (dest, true), src));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The operation can be split into two normal moves. Decide in
|
||||
which order to do them. */
|
||||
rtx low_dest;
|
||||
|
||||
low_dest = mips_subword (dest, false);
|
||||
if (REG_P (low_dest)
|
||||
&& reg_overlap_mentioned_p (low_dest, src))
|
||||
|
@ -3600,8 +3600,9 @@ mips_output_move (rtx dest, rtx src)
|
|||
if (GP_REG_P (REGNO (dest)))
|
||||
return "move\t%0,%z1";
|
||||
|
||||
if (MD_REG_P (REGNO (dest)))
|
||||
return "mt%0\t%z1";
|
||||
/* Moves to HI are handled by special .md insns. */
|
||||
if (REGNO (dest) == LO_REGNUM)
|
||||
return "mtlo\t%z1";
|
||||
|
||||
if (DSP_ACC_REG_P (REGNO (dest)))
|
||||
{
|
||||
|
@ -3624,14 +3625,29 @@ mips_output_move (rtx dest, rtx src)
|
|||
}
|
||||
}
|
||||
if (dest_code == MEM)
|
||||
return dbl_p ? "sd\t%z1,%0" : "sw\t%z1,%0";
|
||||
switch (GET_MODE_SIZE (mode))
|
||||
{
|
||||
case 1: return "sb\t%z1,%0";
|
||||
case 2: return "sh\t%z1,%0";
|
||||
case 4: return "sw\t%z1,%0";
|
||||
case 8: return "sd\t%z1,%0";
|
||||
}
|
||||
}
|
||||
if (dest_code == REG && GP_REG_P (REGNO (dest)))
|
||||
{
|
||||
if (src_code == REG)
|
||||
{
|
||||
/* Handled by separate patterns. */
|
||||
gcc_assert (!MD_REG_P (REGNO (src)));
|
||||
/* Moves from HI are handled by special .md insns. */
|
||||
if (REGNO (src) == LO_REGNUM)
|
||||
{
|
||||
/* When generating VR4120 or VR4130 code, we use MACC and
|
||||
DMACC instead of MFLO. This avoids both the normal
|
||||
MIPS III HI/LO hazards and the errata related to
|
||||
-mfix-vr4130. */
|
||||
if (ISA_HAS_MACCHI)
|
||||
return dbl_p ? "dmacc\t%0,%.,%." : "macc\t%0,%.,%.";
|
||||
return "mflo\t%0";
|
||||
}
|
||||
|
||||
if (DSP_ACC_REG_P (REGNO (src)))
|
||||
{
|
||||
|
@ -3658,7 +3674,13 @@ mips_output_move (rtx dest, rtx src)
|
|||
}
|
||||
|
||||
if (src_code == MEM)
|
||||
return dbl_p ? "ld\t%0,%1" : "lw\t%0,%1";
|
||||
switch (GET_MODE_SIZE (mode))
|
||||
{
|
||||
case 1: return "lbu\t%0,%1";
|
||||
case 2: return "lhu\t%0,%1";
|
||||
case 4: return "lw\t%0,%1";
|
||||
case 8: return "ld\t%0,%1";
|
||||
}
|
||||
|
||||
if (src_code == CONST_INT)
|
||||
{
|
||||
|
@ -8954,13 +8976,30 @@ mips_hard_regno_mode_ok_p (unsigned int regno, enum machine_mode mode)
|
|||
if (ACC_REG_P (regno)
|
||||
&& (INTEGRAL_MODE_P (mode) || ALL_FIXED_POINT_MODE_P (mode)))
|
||||
{
|
||||
if (size <= UNITS_PER_WORD)
|
||||
return true;
|
||||
if (MD_REG_P (regno))
|
||||
{
|
||||
/* After a multiplication or division, clobbering HI makes
|
||||
the value of LO unpredictable, and vice versa. This means
|
||||
that, for all interesting cases, HI and LO are effectively
|
||||
a single register.
|
||||
|
||||
if (size <= UNITS_PER_WORD * 2)
|
||||
return (DSP_ACC_REG_P (regno)
|
||||
? ((regno - DSP_ACC_REG_FIRST) & 1) == 0
|
||||
: regno == MD_REG_FIRST);
|
||||
We model this by requiring that any value that uses HI
|
||||
also uses LO. */
|
||||
if (size <= UNITS_PER_WORD * 2)
|
||||
return regno == (size <= UNITS_PER_WORD ? LO_REGNUM : MD_REG_FIRST);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* DSP accumulators do not have the same restrictions as
|
||||
HI and LO, so we can treat them as normal doubleword
|
||||
registers. */
|
||||
if (size <= UNITS_PER_WORD)
|
||||
return true;
|
||||
|
||||
if (size <= UNITS_PER_WORD * 2
|
||||
&& ((regno - DSP_ACC_REG_FIRST) & 1) == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ALL_COP_REG_P (regno))
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -76,9 +76,11 @@
|
|||
(ior (match_test "op == CONST0_RTX (GET_MODE (op))")
|
||||
(match_test "op == CONST1_RTX (GET_MODE (op))"))))
|
||||
|
||||
(define_predicate "fpr_operand"
|
||||
(define_predicate "d_operand"
|
||||
(and (match_code "reg")
|
||||
(match_test "FP_REG_P (REGNO (op))")))
|
||||
(match_test "TARGET_MIPS16
|
||||
? M16_REG_P (REGNO (op))
|
||||
: GP_REG_P (REGNO (op))")))
|
||||
|
||||
(define_predicate "lo_operand"
|
||||
(and (match_code "reg")
|
||||
|
|
|
@ -2469,13 +2469,15 @@ generating MIPS16 code.
|
|||
A floating-point register (if available).
|
||||
|
||||
@item h
|
||||
The @code{hi} register.
|
||||
Formerly the @code{hi} register. This constraint is no longer supported.
|
||||
|
||||
@item l
|
||||
The @code{lo} register.
|
||||
The @code{lo} register. Use this register to store values that are
|
||||
no bigger than a word.
|
||||
|
||||
@item x
|
||||
The @code{hi} and @code{lo} registers.
|
||||
The concatenated @code{hi} and @code{lo} registers. Use this register
|
||||
to store doubleword values.
|
||||
|
||||
@item c
|
||||
A register suitable for use in an indirect jump. This will always be
|
||||
|
|
|
@ -623,12 +623,12 @@ UDItype __umulsidi3 (USItype, USItype);
|
|||
#endif /* __m88000__ */
|
||||
|
||||
#if defined (__mips__) && W_TYPE_SIZE == 32
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
__asm__ ("multu %2,%3" \
|
||||
: "=l" ((USItype) (w0)), \
|
||||
"=h" ((USItype) (w1)) \
|
||||
: "d" ((USItype) (u)), \
|
||||
"d" ((USItype) (v)))
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
do { \
|
||||
UDItype __x = (UDItype) (USItype) (u) * (USItype) (v); \
|
||||
(w1) = (USItype) (__x >> 32); \
|
||||
(w0) = (USItype) (__x); \
|
||||
} while (0)
|
||||
#define UMUL_TIME 10
|
||||
#define UDIV_TIME 100
|
||||
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
2008-06-09 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* gcc.dg/torture/mips-hilo-1.c: Delete.
|
||||
* gcc.target/mips/pr35232.c: Likewise.
|
||||
* gcc.target/mips/fix-vr4130-1.c: Use modulus to create an mfhi.
|
||||
* gcc.target/mips/fix-vr4130-3.c: Likewise.
|
||||
* gcc.target/mips/int-moves-1.c: New test.
|
||||
* gcc.target/mips/int-moves-2.c: Likewise.
|
||||
* gcc.target/mips/fix-r4000-1.c: Likewise.
|
||||
* gcc.target/mips/fix-r4000-2.c: Likewise.
|
||||
* gcc.target/mips/fix-r4000-3.c: Likewise.
|
||||
* gcc.target/mips/fix-r4000-4.c: Likewise.
|
||||
* gcc.target/mips/fix-r4000-5.c: Likewise.
|
||||
* gcc.target/mips/fix-r4000-6.c: Likewise.
|
||||
* gcc.target/mips/fix-r4000-7.c: Likewise.
|
||||
* gcc.target/mips/fix-r4000-8.c: Likewise.
|
||||
* gcc.target/mips/fix-r4000-9.c: Likewise.
|
||||
* gcc.target/mips/fix-r4000-10.c: Likewise.
|
||||
* gcc.target/mips/fix-r4000-11.c: Likewise.
|
||||
* gcc.target/mips/fix-r4000-12.c: Likewise.
|
||||
* gcc.target/mips/timode-1.c: Likewise.
|
||||
* gcc.target/mips/timode-2.c: Likewise.
|
||||
|
||||
2008-06-09 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gnat.dg/specs/pack3.ads: New test.
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
/* f1 checks that an mtlo is not moved before an mfhi. f2 does the same
|
||||
for an mthi and an mflo. */
|
||||
/* { dg-do run { target mips*-*-* } } */
|
||||
/* { dg-options "-mtune=rm7000" } */
|
||||
|
||||
extern void abort (void);
|
||||
extern void exit (int);
|
||||
|
||||
#define DECLARE(TYPE) \
|
||||
TYPE __attribute__ ((noinline)) __attribute__ ((nomips16)) \
|
||||
f1##TYPE (TYPE x1, TYPE x2, TYPE x3) \
|
||||
{ \
|
||||
TYPE t1, t2; \
|
||||
\
|
||||
asm ("mult\t%1,%2" : "=h" (t1) : "d" (x1), "d" (x2) : "lo"); \
|
||||
asm ("mflo\t%0" : "=r" (t2) : "l" (x3) : "hi"); \
|
||||
return t1 + t2; \
|
||||
} \
|
||||
\
|
||||
TYPE __attribute__ ((noinline)) __attribute__ ((nomips16)) \
|
||||
f2##TYPE (TYPE x1, TYPE x2, TYPE x3) \
|
||||
{ \
|
||||
TYPE t1, t2; \
|
||||
\
|
||||
asm ("mult\t%1,%2" : "=l" (t1) : "d" (x1), "d" (x2) : "hi"); \
|
||||
asm ("mfhi\t%0" : "=r" (t2) : "h" (x3) : "lo"); \
|
||||
return t1 + t2; \
|
||||
}
|
||||
|
||||
#define TEST(TYPE) \
|
||||
if (f1##TYPE (1, 2, 10) != 10) \
|
||||
abort (); \
|
||||
if (f2##TYPE (1, 2, 40) != 42) \
|
||||
abort ()
|
||||
|
||||
typedef char c;
|
||||
typedef signed char sc;
|
||||
typedef unsigned char uc;
|
||||
typedef short s;
|
||||
typedef unsigned short us;
|
||||
typedef int i;
|
||||
typedef unsigned int ui;
|
||||
typedef long long ll;
|
||||
typedef unsigned long long ull;
|
||||
|
||||
DECLARE (c)
|
||||
DECLARE (sc)
|
||||
DECLARE (uc)
|
||||
DECLARE (s)
|
||||
DECLARE (us)
|
||||
DECLARE (i)
|
||||
DECLARE (ui)
|
||||
#if defined (__mips64)
|
||||
DECLARE (ll)
|
||||
DECLARE (ull)
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
TEST (c);
|
||||
TEST (sc);
|
||||
TEST (uc);
|
||||
TEST (s);
|
||||
TEST (us);
|
||||
TEST (i);
|
||||
TEST (ui);
|
||||
#if defined (__mips64)
|
||||
TEST (ll);
|
||||
TEST (ull);
|
||||
#endif
|
||||
exit (0);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
/* { dg-mips-options "-march=r4000 -mfix-r4000 -O2 -dp" } */
|
||||
typedef int int32_t;
|
||||
typedef int uint32_t;
|
||||
int32_t foo (int32_t x, int32_t y) { return x * y; }
|
||||
uint32_t bar (uint32_t x, uint32_t y) { return x * y; }
|
||||
/* { dg-final { scan-assembler-times "[concat {\tmult\t\$[45],\$[45][^\n]+mulsi3_r4000[^\n]+\n\tmflo\t\$2\n}]" 2 } } */
|
|
@ -0,0 +1,8 @@
|
|||
/* ??? At the moment, lower-subreg.c decomposes the copy of the multiplication
|
||||
result to $2, which prevents the register allocators from storing the
|
||||
multiplication result in $2. */
|
||||
/* { dg-mips-options "-mips3 -mfix-r4000 -mgp64 -O2 -fno-split-wide-types -dp -EL" } */
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef unsigned int uint128_t __attribute__((mode(TI)));
|
||||
uint128_t foo (uint64_t x, uint64_t y) { return (uint128_t) x * y; }
|
||||
/* { dg-final { scan-assembler "[concat {\tdmultu\t\$[45],\$[45][^\n]+umulditi3_r4000[^\n]+\n\tmflo\t\$2\n\tmfhi\t\$3\n}]" } } */
|
|
@ -0,0 +1,4 @@
|
|||
/* { dg-mips-options "-march=r4000 -mfix-r4000 -mgp64 -O2 -dp" } */
|
||||
typedef long long int64_t;
|
||||
int64_t foo (int64_t x) { return x / 11993; }
|
||||
/* { dg-final { scan-assembler "[concat {\tdmult\t\$4,\$[0-9]+[^\n]+smuldi3_highpart[^\n]+\n\tmfhi\t\$[0-9]+\n}]" } } */
|
|
@ -0,0 +1,4 @@
|
|||
/* { dg-mips-options "-march=r4000 -mfix-r4000 -mgp64 -O2 -dp" } */
|
||||
typedef unsigned long long uint64_t;
|
||||
uint64_t foo (uint64_t x) { return x / 11993; }
|
||||
/* { dg-final { scan-assembler "[concat {\tdmultu\t\$4,\$[0-9]+[^\n]+umuldi3_highpart[^\n]+\n\tmfhi\t\$[0-9]+\n}]" } } */
|
|
@ -0,0 +1,7 @@
|
|||
/* { dg-mips-options "-mips1 -mfix-r4000 -O2 -dp -EB" } */
|
||||
typedef int int32_t;
|
||||
typedef long long int64_t;
|
||||
int32_t foo (int32_t x, int32_t y) { return ((int64_t) x * y) >> 32; }
|
||||
/* ??? A highpart pattern would be a better choice, but we currently
|
||||
don't use them. */
|
||||
/* { dg-final { scan-assembler "[concat {\tmult\t\$[45],\$[45][^\n]+mulsidi3_32bit_r4000[^\n]+\n\tmflo\t\$3\n\tmfhi\t\$2\n}]" } } */
|
|
@ -0,0 +1,7 @@
|
|||
/* { dg-mips-options "-mips1 -mfix-r4000 -O2 -dp -EB" } */
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
uint32_t foo (uint32_t x, uint32_t y) { return ((uint64_t) x * y) >> 32; }
|
||||
/* ??? A highpart pattern would be a better choice, but we currently
|
||||
don't use them. */
|
||||
/* { dg-final { scan-assembler "[concat {\tmultu\t\$[45],\$[45][^\n]+umulsidi3_32bit_r4000[^\n]+\n\tmflo\t\$3\n\tmfhi\t\$2\n}]" } } */
|
|
@ -0,0 +1,8 @@
|
|||
/* ??? At the moment, lower-subreg.c decomposes the copy of the multiplication
|
||||
result to $2, which prevents the register allocators from storing the
|
||||
multiplication result in $2. */
|
||||
/* { dg-mips-options "-mips1 -mfix-r4000 -O2 -fno-split-wide-types -dp -EL" } */
|
||||
typedef int int32_t;
|
||||
typedef long long int64_t;
|
||||
int64_t foo (int32_t x, int32_t y) { return (int64_t) x * y; }
|
||||
/* { dg-final { scan-assembler "[concat {\tmult\t\$[45],\$[45][^\n]+mulsidi3_32bit_r4000[^\n]+\n\tmflo\t\$2\n\tmfhi\t\$3\n}]" } } */
|
|
@ -0,0 +1,8 @@
|
|||
/* ??? At the moment, lower-subreg.c decomposes the copy of the multiplication
|
||||
result to $2, which prevents the register allocators from storing the
|
||||
multiplication result in $2. */
|
||||
/* { dg-mips-options "-mips1 -mfix-r4000 -O2 -fno-split-wide-types -dp -EL" } */
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
uint64_t foo (uint32_t x, uint32_t y) { return (uint64_t) x * y; }
|
||||
/* { dg-final { scan-assembler "[concat {\tmultu\t\$[45],\$[45][^\n]+umulsidi3_32bit_r4000[^\n]+\n\tmflo\t\$2\n\tmfhi\t\$3\n}]" } } */
|
|
@ -0,0 +1,6 @@
|
|||
/* { dg-mips-options "-march=r4000 -mfix-r4000 -mgp64 -O2 -dp" } */
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
int64_t foo (int64_t x, int64_t y) { return x * y; }
|
||||
uint64_t bar (uint64_t x, uint64_t y) { return x * y; }
|
||||
/* { dg-final { scan-assembler-times "[concat {\tdmult\t\$[45],\$[45][^\n]+muldi3_r4000[^\n]+\n\tmflo\t\$2\n}]" 2 } } */
|
|
@ -0,0 +1,7 @@
|
|||
/* { dg-mips-options "-march=r4000 -mfix-r4000 -O2 -mgp64 -dp -EB" } */
|
||||
typedef long long int64_t;
|
||||
typedef int int128_t __attribute__((mode(TI)));
|
||||
int64_t foo (int64_t x, int64_t y) { return ((int128_t) x * y) >> 64; }
|
||||
/* ??? A highpart pattern would be a better choice, but we currently
|
||||
don't use them. */
|
||||
/* { dg-final { scan-assembler "[concat {\tdmult\t\$[45],\$[45][^\n]+mulditi3[^\n]+\n\tmflo\t\$3\n\tmfhi\t\$2\n}]" } } */
|
|
@ -0,0 +1,7 @@
|
|||
/* { dg-mips-options "-march=r4000 -mfix-r4000 -O2 -mgp64 -dp -EB" } */
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef unsigned int uint128_t __attribute__((mode(TI)));
|
||||
uint64_t foo (uint64_t x, uint64_t y) { return ((uint128_t) x * y) >> 64; }
|
||||
/* ??? A highpart pattern would be a better choice, but we currently
|
||||
don't use them. */
|
||||
/* { dg-final { scan-assembler "[concat {\tdmultu\t\$[45],\$[45][^\n]+umulditi3[^\n]+\n\tmflo\t\$3\n\tmfhi\t\$2\n}]" } } */
|
|
@ -0,0 +1,8 @@
|
|||
/* ??? At the moment, lower-subreg.c decomposes the copy of the multiplication
|
||||
result to $2, which prevents the register allocators from storing the
|
||||
multiplication result in $2. */
|
||||
/* { dg-mips-options "-mips3 -mfix-r4000 -mgp64 -O2 -fno-split-wide-types -dp -EL" } */
|
||||
typedef long long int64_t;
|
||||
typedef int int128_t __attribute__((mode(TI)));
|
||||
int128_t foo (int64_t x, int64_t y) { return (int128_t) x * y; }
|
||||
/* { dg-final { scan-assembler "[concat {\tdmult\t\$[45],\$[45][^\n]+mulditi3_r4000[^\n]+\n\tmflo\t\$2\n\tmfhi\t\$3\n}]" } } */
|
|
@ -1,4 +1,8 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-mips-options "-march=vr4130 -mfix-vr4130" } */
|
||||
NOMIPS16 int foo (void) { int r; asm ("# foo" : "=h" (r)); return r; }
|
||||
NOMIPS16 unsigned int
|
||||
foo (unsigned int x, unsigned int y)
|
||||
{
|
||||
return x % y;
|
||||
}
|
||||
/* { dg-final { scan-assembler "\tmacchi\t" } } */
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-mips-options "-march=vr4130 -mgp64 -mfix-vr4130" } */
|
||||
NOMIPS16 long long
|
||||
foo (void)
|
||||
NOMIPS16 unsigned long long
|
||||
foo (unsigned long long x, unsigned long long y)
|
||||
{
|
||||
long long r;
|
||||
asm ("# foo" : "=h" (r));
|
||||
return r;
|
||||
return x % y;
|
||||
}
|
||||
/* { dg-final { scan-assembler "\tdmacchi\t" } } */
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/* { dg-do compile { target mips16_attribute } } */
|
||||
/* { dg-mips-options "-mgp64 -msoft-float -O2 -EL" } */
|
||||
/* { dg-add-options mips16_attribute } */
|
||||
|
||||
typedef unsigned uint128_t __attribute__((mode(TI)));
|
||||
|
||||
extern uint128_t g[16];
|
||||
extern unsigned char gstuff[0x10000];
|
||||
|
||||
NOMIPS16 uint128_t
|
||||
foo (uint128_t i1, uint128_t i2, uint128_t i3, uint128_t i4,
|
||||
uint128_t *x, unsigned char *lstuff)
|
||||
{
|
||||
g[0] = i1;
|
||||
g[1] = i2;
|
||||
g[2] = i3;
|
||||
g[3] = i4;
|
||||
x[0] = x[4];
|
||||
x[1] = 0;
|
||||
x[2] = ((uint128_t) 0x123456789abcdefULL << 64) | 0xaabbccddeeff1122ULL;
|
||||
x[3] = g[4];
|
||||
x[4] = *(uint128_t *) (lstuff + 0x7fff);
|
||||
return *(uint128_t *) (gstuff + 0x7fff);
|
||||
}
|
||||
|
||||
MIPS16 uint128_t
|
||||
bar (uint128_t i1, uint128_t i2, uint128_t i3, uint128_t i4,
|
||||
uint128_t *x, unsigned char *lstuff)
|
||||
{
|
||||
g[0] = i1;
|
||||
g[1] = i2;
|
||||
g[2] = i3;
|
||||
g[3] = i4;
|
||||
x[0] = x[4];
|
||||
x[1] = 0;
|
||||
x[2] = ((uint128_t) 0x123456789abcdefULL << 64) | 0xaabbccddeeff1122ULL;
|
||||
x[3] = g[4];
|
||||
x[4] = *(uint128_t *) (lstuff + 0x7fff);
|
||||
return *(uint128_t *) (gstuff + 0x7fff);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/* { dg-do compile { target mips16_attribute } } */
|
||||
/* { dg-mips-options "-mgp64 -msoft-float -O2 -EB" } */
|
||||
/* { dg-add-options mips16_attribute } */
|
||||
|
||||
typedef unsigned uint128_t __attribute__((mode(TI)));
|
||||
|
||||
extern uint128_t g[16];
|
||||
extern unsigned char gstuff[0x10000];
|
||||
|
||||
NOMIPS16 uint128_t
|
||||
foo (uint128_t i1, uint128_t i2, uint128_t i3, uint128_t i4,
|
||||
uint128_t *x, unsigned char *lstuff)
|
||||
{
|
||||
g[0] = i1;
|
||||
g[1] = i2;
|
||||
g[2] = i3;
|
||||
g[3] = i4;
|
||||
x[0] = x[4];
|
||||
x[1] = 0;
|
||||
x[2] = ((uint128_t) 0x123456789abcdefULL << 64) | 0xaabbccddeeff1122ULL;
|
||||
x[3] = g[4];
|
||||
x[4] = *(uint128_t *) (lstuff + 0x7fff);
|
||||
return *(uint128_t *) (gstuff + 0x7fff);
|
||||
}
|
||||
|
||||
MIPS16 uint128_t
|
||||
bar (uint128_t i1, uint128_t i2, uint128_t i3, uint128_t i4,
|
||||
uint128_t *x, unsigned char *lstuff)
|
||||
{
|
||||
g[0] = i1;
|
||||
g[1] = i2;
|
||||
g[2] = i3;
|
||||
g[3] = i4;
|
||||
x[0] = x[4];
|
||||
x[1] = 0;
|
||||
x[2] = ((uint128_t) 0x123456789abcdefULL << 64) | 0xaabbccddeeff1122ULL;
|
||||
x[3] = g[4];
|
||||
x[4] = *(uint128_t *) (lstuff + 0x7fff);
|
||||
return *(uint128_t *) (gstuff + 0x7fff);
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-mips-options "-O" } */
|
||||
|
||||
NOMIPS16 unsigned int
|
||||
f1 (unsigned long long x)
|
||||
{
|
||||
unsigned int r;
|
||||
asm ("# %0" : "=a" (r) : "0" (x));
|
||||
asm ("# %0" : "=h" (r) : "0" (r));
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return f1 (4) != 4;
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/* { dg-mips-options "-mgp64" } */
|
||||
typedef int int128_t __attribute__((mode(TI)));
|
||||
typedef unsigned int uint128_t __attribute__((mode(TI)));
|
||||
|
||||
#define UINT128_CONST(A, B) \
|
||||
(((uint128_t) (0x ## A ## ULL) << 64) | (0x ## B ## ULL))
|
||||
|
||||
volatile uint128_t a = UINT128_CONST (1111111111111111, a222222222222222);
|
||||
volatile uint128_t b = UINT128_CONST (0000000000000005, 0000000000000003);
|
||||
volatile uint128_t c = UINT128_CONST (5dddddddddddddde, e666666666666666);
|
||||
volatile uint128_t d = UINT128_CONST (e612340000000000, 5000000000234500);
|
||||
volatile uint128_t e = UINT128_CONST (43f011dddddddddf, 366666666689ab66);
|
||||
volatile uint128_t f = UINT128_CONST (4210100000000000, 1000000000010100);
|
||||
volatile uint128_t g = UINT128_CONST (a5e225dddddddddf, 6666666666aaee66);
|
||||
volatile uint128_t h = UINT128_CONST (e7f235dddddddddf, 7666666666abef66);
|
||||
volatile uint128_t i = UINT128_CONST (5e225dddddddddf6, 666666666aaee660);
|
||||
volatile uint128_t j = UINT128_CONST (0a5e225ddddddddd, f6666666666aaee6);
|
||||
volatile uint128_t k = UINT128_CONST (fa5e225ddddddddd, f6666666666aaee6);
|
||||
|
||||
volatile int amount = 4;
|
||||
|
||||
volatile uint128_t result;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
result = a * b;
|
||||
if (result != c)
|
||||
return 1;
|
||||
|
||||
result = c + d;
|
||||
if (result != e)
|
||||
return 1;
|
||||
|
||||
result = e - d;
|
||||
if (result != c)
|
||||
return 1;
|
||||
|
||||
result = d & e;
|
||||
if (result != f)
|
||||
return 1;
|
||||
|
||||
result = d ^ e;
|
||||
if (result != g)
|
||||
return 1;
|
||||
|
||||
result = d | e;
|
||||
if (result != h)
|
||||
return 1;
|
||||
|
||||
result = g << amount;
|
||||
if (result != i)
|
||||
return 1;
|
||||
|
||||
result = g >> amount;
|
||||
if (result != j)
|
||||
return 1;
|
||||
|
||||
result = (int128_t) g >> amount;
|
||||
if (result != k)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* { dg-final { scan-assembler-not "\tjal" } } */
|
|
@ -0,0 +1,64 @@
|
|||
/* { dg-do run { target mips64 } } */
|
||||
typedef int int128_t __attribute__((mode(TI)));
|
||||
typedef unsigned int uint128_t __attribute__((mode(TI)));
|
||||
|
||||
#define UINT128_CONST(A, B) \
|
||||
(((uint128_t) (0x ## A ## ULL) << 64) | (0x ## B ## ULL))
|
||||
|
||||
volatile uint128_t a = UINT128_CONST (1111111111111111, a222222222222222);
|
||||
volatile uint128_t b = UINT128_CONST (0000000000000005, 0000000000000003);
|
||||
volatile uint128_t c = UINT128_CONST (5dddddddddddddde, e666666666666666);
|
||||
volatile uint128_t d = UINT128_CONST (e612340000000000, 5000000000234500);
|
||||
volatile uint128_t e = UINT128_CONST (43f011dddddddddf, 366666666689ab66);
|
||||
volatile uint128_t f = UINT128_CONST (4210100000000000, 1000000000010100);
|
||||
volatile uint128_t g = UINT128_CONST (a5e225dddddddddf, 6666666666aaee66);
|
||||
volatile uint128_t h = UINT128_CONST (e7f235dddddddddf, 7666666666abef66);
|
||||
volatile uint128_t i = UINT128_CONST (5e225dddddddddf6, 666666666aaee660);
|
||||
volatile uint128_t j = UINT128_CONST (0a5e225ddddddddd, f6666666666aaee6);
|
||||
volatile uint128_t k = UINT128_CONST (fa5e225ddddddddd, f6666666666aaee6);
|
||||
|
||||
volatile int amount = 4;
|
||||
|
||||
volatile uint128_t result;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
result = a * b;
|
||||
if (result != c)
|
||||
return 1;
|
||||
|
||||
result = c + d;
|
||||
if (result != e)
|
||||
return 1;
|
||||
|
||||
result = e - d;
|
||||
if (result != c)
|
||||
return 1;
|
||||
|
||||
result = d & e;
|
||||
if (result != f)
|
||||
return 1;
|
||||
|
||||
result = d ^ e;
|
||||
if (result != g)
|
||||
return 1;
|
||||
|
||||
result = d | e;
|
||||
if (result != h)
|
||||
return 1;
|
||||
|
||||
result = g << amount;
|
||||
if (result != i)
|
||||
return 1;
|
||||
|
||||
result = g >> amount;
|
||||
if (result != j)
|
||||
return 1;
|
||||
|
||||
result = (int128_t) g >> amount;
|
||||
if (result != k)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue