* doc/invoke.texi (-mpaired-single): Don't say that the option
requires 64-bit code.
* config/mips/mips-protos.h (mips_modes_tieable_p): Declare.
* config/mips/mips.h (ISA_HAS_PAIRED_SINGLE): New macro.
(ISA_HAS_NMADD_NMSUB): Add a mode argument. Return true for
V2SF if ISA_MIPS32R2.
(MODES_TIEABLE_P): Use mips_modes_tieable_p.
* config/mips/mips.c (mips_rtx_costs): Pass a mode argument
to ISA_HAS_NMADD_NMSUB.
(mips_split_doubleword_move): Handle V2SF.
(mips_modes_tieable_p): New function.
(override_options): Report a warning rather than an error when
-mpaired-single is used on ISAs that don't support it; use
ISA_HAS_PAIRED_SINGLE to check that case.
* config/mips/mips.md (MOVE64): New mode iterator. Replace DI
and DF move splitters with a single MOVE64 splitter, thereby adding
a V2SF splitter too.
(SPLITF): Add TARGET_DOUBLE_FLOAT conditions to DI and DF.
Add a TARGET_FLOAT64 condition to TF. Add V2SF to the iterator.
(HALFMODE): Add V2SF.
(*nmadd<mode>, *nmadd<mode>_fastmath, *nmsub<mode>)
(*nmsub<mode>_fastmath): Add a mode argument to ISA_HAS_NMADD_NMSUB.
(movv2sf_hardfloat_64bit): Tweak ordering of conditions.
(movv2sf_hardfloat_32bit): New pattern.
(load_low<mode>, load_high<mode>, store_word<mode>): Remove
TARGET_DOUBLE_FLOAT conditions.
gcc/testsuite/
* gcc.dg/vect/vect.exp: Extend -mpaired-single handling to all
MIPS targets.
* g++.dg/vect/vect.exp: Likewise.
* lib/fortran-torture.exp: Likewise.
* gcc.target/mips/mips-ps-1.c: Use mpaired_single rather than
mipsisa64*-*-* as the target selector. Remove -mips64,
-mhard-float and -mgp64 from the options list.
* gcc.target/mips/mips-ps-2.c: Likewise.
* gcc.target/mips/mips-ps-3.c: Likewise.
* gcc.target/mips/mips-ps-4.c: Likewise.
* gcc.target/mips/mips-ps-6.c: Likewise.
* gcc.target/mips/mips-ps-5.c: Remove -mhard-float from the
options list.
* gcc.target/mips/sb1-1.c: Likewise.
* gcc.target/mips/mips-ps-type.c: Likewise.
* gcc.target/mips/mips-ps-7.c: New test.
* gcc.target/mips/mips-ps-type-2.c: Likewise.
* gcc.target/mips/fpr-moves-6.c: Remove XFAIL.
* gcc.target/mips/mips.exp (setup_mips_tests): Set mips_fp and
mips_gp instead of mips_fp64 and mips_gp64. Treat -mgp32 -mfp64
as forcing an ABI and an architecture.
(is_gp32_flag, is_gp64_flag): Fold into...
(dg-mips-options): ...here. Make -mpaired-single imply -mfp64,
then -mfp64 imply -mhard-float. Apply register rules after the
loop. Handle -march=mipsN like -mipsN.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129522
138bc75d-0d04-0410-961f-
82ee72b054a4
+2007-10-21 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * doc/invoke.texi (-mpaired-single): Don't say that the option
+ requires 64-bit code.
+ * config/mips/mips-protos.h (mips_modes_tieable_p): Declare.
+ * config/mips/mips.h (ISA_HAS_PAIRED_SINGLE): New macro.
+ (ISA_HAS_NMADD_NMSUB): Add a mode argument. Return true for
+ V2SF if ISA_MIPS32R2.
+ (MODES_TIEABLE_P): Use mips_modes_tieable_p.
+ * config/mips/mips.c (mips_rtx_costs): Pass a mode argument
+ to ISA_HAS_NMADD_NMSUB.
+ (mips_split_doubleword_move): Handle V2SF.
+ (mips_modes_tieable_p): New function.
+ (override_options): Report a warning rather than an error when
+ -mpaired-single is used on ISAs that don't support it; use
+ ISA_HAS_PAIRED_SINGLE to check that case.
+ * config/mips/mips.md (MOVE64): New mode iterator. Replace DI
+ and DF move splitters with a single MOVE64 splitter, thereby adding
+ a V2SF splitter too.
+ (SPLITF): Add TARGET_DOUBLE_FLOAT conditions to DI and DF.
+ Add a TARGET_FLOAT64 condition to TF. Add V2SF to the iterator.
+ (HALFMODE): Add V2SF.
+ (*nmadd<mode>, *nmadd<mode>_fastmath, *nmsub<mode>)
+ (*nmsub<mode>_fastmath): Add a mode argument to ISA_HAS_NMADD_NMSUB.
+ (movv2sf_hardfloat_64bit): Tweak ordering of conditions.
+ (movv2sf_hardfloat_32bit): New pattern.
+ (load_low<mode>, load_high<mode>, store_word<mode>): Remove
+ TARGET_DOUBLE_FLOAT conditions.
+
2007-10-20 Jakub Jelinek <jakub@redhat.com>
* config/rs6000/linux-unwind.h (ppc_fallback_frame_state): Point
extern bool mips_cannot_change_mode_class (enum machine_mode,
enum machine_mode, enum reg_class);
extern bool mips_dangerous_for_la25_p (rtx);
+extern bool mips_modes_tieable_p (enum machine_mode, enum machine_mode);
extern enum reg_class mips_preferred_reload_class (rtx, enum reg_class);
extern enum reg_class mips_secondary_reload_class (enum reg_class,
enum machine_mode,
case MINUS:
if (float_mode_p
- && ISA_HAS_NMADD_NMSUB
+ && ISA_HAS_NMADD_NMSUB (mode)
&& TARGET_FUSED_MADD
&& !HONOR_NANS (mode)
&& !HONOR_SIGNED_ZEROS (mode))
case NEG:
if (float_mode_p
- && ISA_HAS_NMADD_NMSUB
+ && ISA_HAS_NMADD_NMSUB (mode)
&& TARGET_FUSED_MADD
&& !HONOR_NANS (mode)
&& HONOR_SIGNED_ZEROS (mode))
emit_insn (gen_move_doubleword_fprdi (dest, src));
else if (!TARGET_64BIT && GET_MODE (dest) == DFmode)
emit_insn (gen_move_doubleword_fprdf (dest, src));
+ else if (!TARGET_64BIT && GET_MODE (dest) == V2SFmode)
+ emit_insn (gen_move_doubleword_fprv2sf (dest, src));
else if (TARGET_64BIT && GET_MODE (dest) == TFmode)
emit_insn (gen_move_doubleword_fprtf (dest, src));
else
}
}
+/* Implement MODES_TIEABLE_P. */
+
+bool
+mips_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
+{
+ /* FPRs allow no mode punning, so it's not worth tying modes if we'd
+ prefer to put one of them in FPRs. */
+ return (mode1 == mode2
+ || (!mips_mode_ok_for_mov_fmt_p (mode1)
+ && !mips_mode_ok_for_mov_fmt_p (mode2)));
+}
+
/* Implement PREFERRED_RELOAD_CLASS. */
enum reg_class
/* Make sure that the ISA supports TARGET_PAIRED_SINGLE_FLOAT when it is
enabled. */
- if (TARGET_PAIRED_SINGLE_FLOAT && !ISA_MIPS64)
- error ("-mips3d/-mpaired-single must be used with -mips64");
+ if (TARGET_PAIRED_SINGLE_FLOAT && !ISA_HAS_PAIRED_SINGLE)
+ warning (0, "the %qs architecture does not support paired-single"
+ " instructions", mips_arch_info->name);
/* If TARGET_DSPR2, enable MASK_DSP. */
if (TARGET_DSPR2)
|| ISA_MIPS64) \
&& !TARGET_MIPS16)
+/* ISA has paired-single instructions. */
+#define ISA_HAS_PAIRED_SINGLE (ISA_MIPS32R2 || ISA_MIPS64)
+
/* ISA has conditional trap instructions. */
#define ISA_HAS_COND_TRAP (!ISA_MIPS1 \
&& !TARGET_MIPS16)
/* Integer multiply-accumulate instructions should be generated. */
#define GENERATE_MADD_MSUB (ISA_HAS_MADD_MSUB && !TUNE_74K)
-/* ISA has floating-point nmadd and nmsub instructions. */
-#define ISA_HAS_NMADD_NMSUB ((ISA_MIPS4 \
+/* ISA has floating-point nmadd and nmsub instructions for mode MODE. */
+#define ISA_HAS_NMADD_NMSUB(MODE) \
+ ((ISA_MIPS4 \
+ || (ISA_MIPS32R2 && (MODE) == V2SFmode) \
|| ISA_MIPS64) \
&& (!TARGET_MIPS5400 || TARGET_MAD) \
&& !TARGET_MIPS16)
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
mips_hard_regno_mode_ok[ (int)(MODE) ][ (REGNO) ]
-/* Value is 1 if it is a good idea to tie two pseudo registers
- when one has mode MODE1 and one has mode MODE2.
- If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
- for any hard reg, then this must be 0 for correct output. */
-#define MODES_TIEABLE_P(MODE1, MODE2) \
- ((GET_MODE_CLASS (MODE1) == MODE_FLOAT || \
- GET_MODE_CLASS (MODE1) == MODE_COMPLEX_FLOAT) \
- == (GET_MODE_CLASS (MODE2) == MODE_FLOAT || \
- GET_MODE_CLASS (MODE2) == MODE_COMPLEX_FLOAT))
+#define MODES_TIEABLE_P mips_modes_tieable_p
/* Register to use for pushing function arguments. */
#define STACK_POINTER_REGNUM (GP_REG_FIRST + 29)
;; conditional-move-type condition is needed.
(define_mode_iterator MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
+;; 64-bit modes for which we provide move patterns.
+(define_mode_iterator MOVE64
+ [DI DF (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")])
+
;; This mode iterator allows the QI and HI extension patterns to be
;; defined from the same template.
(define_mode_iterator SHORT [QI HI])
(DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
;; A floating-point mode for which moves involving FPRs may need to be split.
-(define_mode_iterator SPLITF [(DF "!TARGET_64BIT")
- (DI "!TARGET_64BIT")
- (TF "TARGET_64BIT")])
+(define_mode_iterator SPLITF
+ [(DF "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
+ (DI "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
+ (V2SF "!TARGET_64BIT && TARGET_PAIRED_SINGLE_FLOAT")
+ (TF "TARGET_64BIT && TARGET_FLOAT64")])
;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
;; 32-bit version and "dsubu" in the 64-bit version.
;; This attribute gives the integer mode that has half the size of
;; the controlling mode.
-(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
+(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (V2SF "SI") (TF "DI")])
;; This attribute works around the early SB-1 rev2 core "F2" erratum:
;;
(mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
(match_operand:ANYF 2 "register_operand" "f"))
(match_operand:ANYF 3 "register_operand" "f"))))]
- "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
+ "ISA_HAS_NMADD_NMSUB (<MODE>mode)
+ && TARGET_FUSED_MADD
&& HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
"nmadd.<fmt>\t%0,%3,%1,%2"
(mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
(match_operand:ANYF 2 "register_operand" "f"))
(match_operand:ANYF 3 "register_operand" "f")))]
- "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
+ "ISA_HAS_NMADD_NMSUB (<MODE>mode)
+ && TARGET_FUSED_MADD
&& !HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
"nmadd.<fmt>\t%0,%3,%1,%2"
(mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
(match_operand:ANYF 3 "register_operand" "f"))
(match_operand:ANYF 1 "register_operand" "f"))))]
- "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
+ "ISA_HAS_NMADD_NMSUB (<MODE>mode)
+ && TARGET_FUSED_MADD
&& HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
"nmsub.<fmt>\t%0,%1,%2,%3"
(match_operand:ANYF 1 "register_operand" "f")
(mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
(match_operand:ANYF 3 "register_operand" "f"))))]
- "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
+ "ISA_HAS_NMADD_NMSUB (<MODE>mode)
+ && TARGET_FUSED_MADD
&& !HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
"nmsub.<fmt>\t%0,%1,%2,%3"
(set_attr "length" "16")])
(define_split
- [(set (match_operand:DI 0 "nonimmediate_operand")
- (match_operand:DI 1 "move_operand"))]
- "reload_completed && !TARGET_64BIT
- && mips_split_64bit_move_p (operands[0], operands[1])"
- [(const_int 0)]
-{
- mips_split_doubleword_move (operands[0], operands[1]);
- DONE;
-})
-
-(define_split
- [(set (match_operand:DF 0 "nonimmediate_operand")
- (match_operand:DF 1 "move_operand"))]
+ [(set (match_operand:MOVE64 0 "nonimmediate_operand")
+ (match_operand:MOVE64 1 "move_operand"))]
"reload_completed && !TARGET_64BIT
&& mips_split_64bit_move_p (operands[0], operands[1])"
[(const_int 0)]
[(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
(match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
"TARGET_HARD_FLOAT
- && TARGET_64BIT
&& TARGET_PAIRED_SINGLE_FLOAT
+ && TARGET_64BIT
&& (register_operand (operands[0], V2SFmode)
|| reg_or_0_operand (operands[1], V2SFmode))"
{ return mips_output_move (operands[0], operands[1]); }
(set_attr "mode" "SF")
(set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
+(define_insn "movv2sf_hardfloat_32bit"
+ [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
+ (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
+ "TARGET_HARD_FLOAT
+ && TARGET_PAIRED_SINGLE_FLOAT
+ && !TARGET_64BIT
+ && (register_operand (operands[0], V2SFmode)
+ || reg_or_0_operand (operands[1], V2SFmode))"
+ { return mips_output_move (operands[0], operands[1]); }
+ [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
+ (set_attr "mode" "SF")
+ (set_attr "length" "4,8,*,*,*,8,8,8,*,*")])
+
;; The HI and LO registers are not truly independent. If we move an mthi
;; instruction before an mflo instruction, it will make the result of the
;; mflo unpredictable. The same goes for mtlo and mfhi.
[(set (match_operand:SPLITF 0 "register_operand" "=f,f")
(unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")]
UNSPEC_LOAD_LOW))]
- "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+ "TARGET_HARD_FLOAT"
{
operands[0] = mips_subword (operands[0], 0);
return mips_output_move (operands[0], operands[1]);
(unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")
(match_operand:SPLITF 2 "register_operand" "0,0")]
UNSPEC_LOAD_HIGH))]
- "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+ "TARGET_HARD_FLOAT"
{
operands[0] = mips_subword (operands[0], 1);
return mips_output_move (operands[0], operands[1]);
(unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f,f")
(match_operand 2 "const_int_operand")]
UNSPEC_STORE_WORD))]
- "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+ "TARGET_HARD_FLOAT"
{
operands[1] = mips_subword (operands[1], INTVAL (operands[2]));
return mips_output_move (operands[0], operands[1]);
@opindex mpaired-single
@opindex mno-paired-single
Use (do not use) paired-single floating-point instructions.
-@xref{MIPS Paired-Single Support}. This option can only be used
-when generating 64-bit code and requires hardware floating-point
-support to be enabled.
+@xref{MIPS Paired-Single Support}. This option requires
+hardware floating-point support to be enabled.
@item -mdmx
@itemx -mno-mdmx
+2007-10-21 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * gcc.dg/vect/vect.exp: Extend -mpaired-single handling to all
+ MIPS targets.
+ * g++.dg/vect/vect.exp: Likewise.
+ * lib/fortran-torture.exp: Likewise.
+ * gcc.target/mips/mips-ps-1.c: Use mpaired_single rather than
+ mipsisa64*-*-* as the target selector. Remove -mips64,
+ -mhard-float and -mgp64 from the options list.
+ * gcc.target/mips/mips-ps-2.c: Likewise.
+ * gcc.target/mips/mips-ps-3.c: Likewise.
+ * gcc.target/mips/mips-ps-4.c: Likewise.
+ * gcc.target/mips/mips-ps-6.c: Likewise.
+ * gcc.target/mips/mips-ps-5.c: Remove -mhard-float from the
+ options list.
+ * gcc.target/mips/sb1-1.c: Likewise.
+ * gcc.target/mips/mips-ps-type.c: Likewise.
+ * gcc.target/mips/mips-ps-7.c: New test.
+ * gcc.target/mips/mips-ps-type-2.c: Likewise.
+ * gcc.target/mips/fpr-moves-6.c: Remove XFAIL.
+ * gcc.target/mips/mips.exp (setup_mips_tests): Set mips_fp and
+ mips_gp instead of mips_fp64 and mips_gp64. Treat -mgp32 -mfp64
+ as forcing an ABI and an architecture.
+ (is_gp32_flag, is_gp64_flag): Fold into...
+ (dg-mips-options): ...here. Make -mpaired-single imply -mfp64,
+ then -mfp64 imply -mhard-float. Apply register rules after the
+ loop. Handle -march=mipsN like -mipsN.
+
2007-10-20 David Edelsohn <edelsohn@gnu.org>
* gcc.dg/vect/vect.exp: Use -mcpu=970 instead of 7400.
} elseif { [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] } {
lappend DEFAULT_VECTCFLAGS "-msse2"
set dg-do-what-default run
-} elseif { [istarget "mipsisa64*-*-*"]
+} elseif { [istarget "mips*-*-*"]
&& [check_effective_target_mpaired_single]
&& [check_effective_target_nomips16] } {
lappend DEFAULT_VECTCFLAGS "-mpaired-single"
} elseif { [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] } {
lappend DEFAULT_VECTCFLAGS "-msse2"
set dg-do-what-default run
-} elseif { [istarget "mipsisa64*-*-*"]
+} elseif { [istarget "mips*-*-*"]
&& [check_effective_target_mpaired_single]
&& [check_effective_target_nomips16] } {
lappend DEFAULT_VECTCFLAGS "-mpaired-single"
/* { dg-final { scan-assembler "\tdmtc1\t\\\$0,\\\$f21\n" } } */
/* { dg-final { scan-assembler "\tsd\t\\\$8,16\\\(\\\$6\\\)\n" } } */
/* { dg-final { scan-assembler "\tsd\t\\\$9,24\\\(\\\$6\\\)\n" } } */
-/* We currently move this through a temporary. */
-/* { dg-final { scan-assembler "\tdmtc1\t\\\$10,\\\$f0\n" { xfail mips*-*-* } } } */
+/* { dg-final { scan-assembler "\tdmtc1\t\\\$10,\\\$f0\n" } } */
/* { dg-final { scan-assembler "\tdmtc1\t\\\$11,\\\$f2\n" } } */
-/* { dg-do run { target mipsisa64*-*-* } } */
-/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64" } */
+/* { dg-do run { target mpaired_single } } */
+/* { dg-mips-options "-O2 -mpaired-single" } */
/* Test v2sf calculations */
#include <stdlib.h>
-/* { dg-do run { target mipsisa64*-*-* } } */
-/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64" } */
+/* { dg-do run { target mpaired_single } } */
+/* { dg-mips-options "-O2 -mpaired-single" } */
/* Test MIPS paired-single builtin functions */
#include <stdlib.h>
-/* { dg-do run { target mipsisa64*-*-* } } */
-/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64" } */
+/* { dg-do run { target mpaired_single } } */
+/* { dg-mips-options "-O2 -mpaired-single" } */
/* Test MIPS paired-single conditional move */
#include <stdlib.h>
-/* { dg-do run { target mipsisa64*-*-* } } */
-/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64" } */
+/* { dg-do run { target mpaired_single } } */
+/* { dg-mips-options "-O2 -mpaired-single" } */
/* Test MIPS paired-single comparisons */
#include <stdlib.h>
/* { dg-do compile } */
-/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64 -ftree-vectorize" } */
+/* { dg-mips-options "-mips64 -O2 -mpaired-single -mgp64 -ftree-vectorize" } */
extern float a[], b[], c[];
/* mips-ps-2.c with an extra -ffinite-math-only option. This option
changes the way that abs.ps is handled. */
-/* { dg-do run { target mipsisa64*-*-* } } */
-/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64 -ffinite-math-only" } */
+/* { dg-do run { target mpaired_single } } */
+/* { dg-mips-options "-O2 -mpaired-single -ffinite-math-only" } */
/* Test MIPS paired-single builtin functions */
#include <stdlib.h>
--- /dev/null
+/* mips-ps-5.c with -mips32r2 instead of -mips64. */
+/* { dg-do compile } */
+/* { dg-mips-options "-mips32r2 -O2 -mpaired-single -ftree-vectorize" } */
+
+extern float a[], b[], c[];
+
+NOMIPS16 void
+foo (void)
+{
+ int i;
+ for (i = 0; i < 16; i++)
+ a[i] = b[i] == c[i] + 1 ? b[i] : c[i];
+}
+
+/* { dg-final { scan-assembler "add\\.ps" } } */
+/* { dg-final { scan-assembler "c\\.eq\\.ps" } } */
+/* { dg-final { scan-assembler "mov\[tf\]\\.ps" } } */
--- /dev/null
+/* Test v2sf calculations. The nmadd and nmsub patterns need
+ -ffinite-math-only. */
+/* { dg-do compile } */
+/* { dg-mips-options "-mips32r2 -O2 -mpaired-single -ffinite-math-only" } */
+/* { dg-final { scan-assembler "cvt.ps.s" } } */
+/* { dg-final { scan-assembler "mov.ps" } } */
+/* { dg-final { scan-assembler "ldc1" } } */
+/* { dg-final { scan-assembler "sdc1" } } */
+/* { dg-final { scan-assembler "add.ps" } } */
+/* { dg-final { scan-assembler "sub.ps" } } */
+/* { dg-final { scan-assembler "neg.ps" } } */
+/* { dg-final { scan-assembler "mul.ps" } } */
+/* { dg-final { scan-assembler "madd.ps" } } */
+/* { dg-final { scan-assembler "msub.ps" } } */
+/* { dg-final { scan-assembler "nmadd.ps" } } */
+/* { dg-final { scan-assembler "nmsub.ps" } } */
+/* { dg-final { scan-assembler "movn.ps" } } */
+/* { dg-final { scan-assembler "movz.ps" } } */
+
+typedef float v2sf __attribute__ ((vector_size(8)));
+void gobble (v2sf);
+
+v2sf A = {100, 200};
+
+/* Init from floats */
+NOMIPS16 v2sf init (float a, float b)
+{
+ return (v2sf) {a, b};
+}
+
+/* Move between registers */
+NOMIPS16 v2sf move (v2sf a)
+{
+ return a;
+}
+
+/* Load from memory */
+NOMIPS16 v2sf load ()
+{
+ return A;
+}
+
+/* Store to memory */
+NOMIPS16 void store (v2sf a)
+{
+ A = a;
+}
+
+/* Add */
+NOMIPS16 v2sf add (v2sf a, v2sf b)
+{
+ return a + b;
+}
+
+/* Subtract */
+NOMIPS16 v2sf sub (v2sf a, v2sf b)
+{
+ return a - b;
+}
+
+/* Negate */
+NOMIPS16 v2sf neg (v2sf a)
+{
+ return - a;
+}
+
+/* Multiply */
+NOMIPS16 v2sf mul (v2sf a, v2sf b)
+{
+ return a * b;
+}
+
+/* Multiply and add */
+NOMIPS16 v2sf madd (v2sf a, v2sf b, v2sf c)
+{
+ return a * b + c;
+}
+
+/* Multiply and subtract */
+NOMIPS16 v2sf msub (v2sf a, v2sf b, v2sf c)
+{
+ return a * b - c;
+}
+
+/* Negate Multiply and add */
+NOMIPS16 v2sf nmadd (v2sf a, v2sf b, v2sf c)
+{
+ return - (a * b + c);
+}
+
+/* Negate Multiply and subtract */
+NOMIPS16 v2sf nmsub (v2sf a, v2sf b, v2sf c)
+{
+ return - (a * b - c);
+}
+
+/* Conditional Move */
+NOMIPS16 v2sf cond_move1 (v2sf a, v2sf b, int i)
+{
+ if (i == 0)
+ a = b;
+ gobble (a);
+}
+
+/* Conditional Move */
+NOMIPS16 v2sf cond_move2 (v2sf a, v2sf b, int i)
+{
+ if (i != 0)
+ a = b;
+ gobble (a);
+}
/* Test v2sf calculations. The nmadd and nmsub patterns need
-ffinite-math-only. */
/* { dg-do compile } */
-/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64 -ffinite-math-only" } */
+/* { dg-mips-options "-mips64 -O2 -mpaired-single -mgp64 -ffinite-math-only" } */
/* { dg-final { scan-assembler "cvt.ps.s" } } */
/* { dg-final { scan-assembler "mov.ps" } } */
/* { dg-final { scan-assembler "ldc1" } } */
# $mips_isa: the ISA level specified by __mips
# $mips_isa_rev: the ISA revision specified by __mips_isa_rev
# $mips_arch: the architecture specified by _MIPS_ARCH
-# $mips_gp64: true if 64-bit output is selected
-# $mips_fp64: true if 64-bit FPRs are selected
+# $mips_gp: the number of bytes in a general register
+# $mips_fp: the number of bytes in a floating-point register
# $mips_float: "hard" or "soft"
# $mips_abi: the ABI specified by _MIPS_SIM
#
global mips_isa
global mips_isa_rev
global mips_arch
- global mips_gp64
- global mips_fp64
+ global mips_gp
+ global mips_fp
global mips_float
global mips_abi
#endif
const char *arch = _MIPS_ARCH;
#ifdef __mips64
- int gp64 = 1;
- #endif
- #if __mips_fpr==64
- int fp64 = 1;
+ int gp = 64;
+ #else
+ int gp = 32;
#endif
+ int fp = __mips_fpr;
#ifdef __mips_hard_float
const char *float = "hard";
#else
regexp {isa = ([^;]*)} $output dummy mips_isa
regexp {isa_rev = ([^;]*)} $output dummy mips_isa_rev
regexp {arch = "([^"]*)} $output dummy mips_arch
- set mips_gp64 [regexp {gp64 = 1} $output]
- set mips_fp64 [regexp {fp64 = 1} $output]
+ regexp {gp = ([^;]*)} $output dummy mips_gp
+ regexp {fp = ([^;]*)} $output dummy mips_fp
regexp {float = "([^"]*)} $output dummy mips_float
regexp {abi = "([^"]*)} $output dummy mips_abi
set mips_forced_le [regexp -- {-(EL|mel)[[:>:]]} $compiler_flags]
set mips_forced_gp [regexp -- {-(G|m(|no-)((extern|local)-sdata|gpopt)|mabicalls|mrtp)} $compiler_flags]
set mips_forced_no_er [regexp -- {-mno-explicit-relocs} $compiler_flags]
-}
-# Return true if command-line option FLAG forces 32-bit code.
-proc is_gp32_flag {flag} {
- switch -glob -- $flag {
- -msmartmips -
- -mips[12] -
- -mips32* -
- -march=mips32* -
- -mabi=32 -
- -mgp32 { return 1 }
- default { return 0 }
- }
-}
-
-# Return true if command-line option FLAG forces 64-bit code.
-proc is_gp64_flag {flag} {
- switch -glob -- $flag {
- -mabi=64 -
- -mabi=o64 -
- -mabi=n32 -
- -mgp64 { return 1 }
- default { return 0 }
+ if {$mips_forced_regs && $mips_gp == 32 && $mips_fp == 64} {
+ set mips_forced_abi 1
+ set mips_forced_isa 1
}
}
# flags force a 32-bit ABI or a 32-bit architecture.
#
# -mfp64
-# Force the use of 64-bit floating-point registers on a 32-bit target.
-# Also force -mhard-float and an architecture that supports such a
-# combination, unless these things are already specified by other
-# parts of the given flags.
+# Force the use of 64-bit floating-point registers, even on a
+# 32-bit target. Also force -mhard-float and an architecture that
+# supports such a combination, unless these things are already
+# specified by other parts of the given flags.
#
# -mabi=*
# Force a particular ABI. Skip the test if the multilib flags
# -mexplicit-relocs
# Select explicit relocations. Skip the test if the multilib flags
# force -mno-explicit-relocs.
+#
+# -mpaired-single
+# Select paired-single instructions. Also behave as for -mfp64.
proc dg-mips-options {args} {
upvar dg-extra-tool-flags extra_tool_flags
upvar dg-do-what do_what
global mips_isa
global mips_isa_rev
global mips_arch
- global mips_gp64
- global mips_fp64
+ global mips_gp
+ global mips_fp
global mips_float
global mips_abi
set flags [lindex $args 1]
set matches 1
- # First handle the -mgp* options. Add an architecture option if necessary.
+ # Add implied flags.
foreach flag $flags {
- if {$flag == "-mfp64"} {
- if {!$mips_fp64 && $mips_forced_regs} {
- set matches 0
- } else {
- if {[lsearch -regexp $flags {^-m(hard|soft)-float$}] < 0} {
- append flags " -mhard-float"
- }
- if {[lsearch -regexp $flags {^(-mips|-march)}] < 0} {
- append flags " -mips32r2"
- }
- }
+ if {[string match -mpaired-single $flag]
+ && [lsearch $flags -mfp*] < 0} {
+ append flags " -mfp64"
}
}
foreach flag $flags {
- if {[is_gp32_flag $flag]
- && ($mips_gp64
- || ($mips_fp64 && [lsearch $flags -mfp64] < 0)) } {
- if {$mips_forced_regs || $mips_forced_abi} {
- set matches 0
- } elseif {[lsearch $flags "-mabi=*"] < 0} {
- append flags " -mabi=32"
+ if {[string match -mfp* $flag]
+ && [lsearch -regexp $flags {^-m(hard|soft)-float$}] < 0} {
+ append flags " -mhard-float"
+ }
+ }
+
+ # Handle options that force a particular register size. Add
+ # architecture and ABI options if necessary.
+ set mips_new_gp $mips_gp
+ set mips_new_fp $mips_fp
+ foreach flag $flags {
+ switch -glob -- $flag {
+ -msmartmips -
+ -mips[12] -
+ -mips32* -
+ -march=mips32* -
+ -mabi=32 -
+ -mgp32 {
+ set mips_new_gp 32
}
- } elseif {[is_gp64_flag $flag] && !$mips_gp64} {
- if {$mips_forced_regs || $mips_forced_abi} {
- set matches 0
+ -mabi=64 -
+ -mabi=o64 -
+ -mabi=n32 -
+ -mgp64 {
+ set mips_new_gp 64
+ }
+ -mfp64 {
+ set mips_new_fp 64
+ }
+ }
+ }
+
+ if {$mips_new_gp != $mips_gp || $mips_new_fp != $mips_fp} {
+ if {$mips_forced_regs} {
+ set matches 0
+ }
+ # Select an appropriate ABI.
+ if {[lsearch $flags "-mabi=*"] < 0} {
+ if {$mips_new_gp == 32} {
+ append flags " -mabi=32"
} else {
- if {[lsearch $flags "-mabi=*"] < 0} {
- append flags " -mabi=o64"
- }
- if {[lsearch -regexp $flags {^(-mips|-march)}] < 0} {
- append flags " -mips3"
- }
+ append flags " -mabi=o64"
+ }
+ }
+ # And an appropriate architecture.
+ if {[lsearch -regexp $flags {^(-mips|-march)}] < 0} {
+ if {$mips_new_gp == 64 && $mips_gp == 32} {
+ append flags " -mips3"
+ } elseif {$mips_new_gp == 32 && $mips_new_fp == 64} {
+ append flags " -mips32r2"
}
}
}
+
# Handle the other options.
foreach flag $flags {
if {[regexp -- {^-mabi=(.*)} $flag dummy abi]} {
if {$abi != $mips_abi && $mips_forced_abi} {
set matches 0
}
- } elseif {[regexp -- {^-march=(.*)} $flag dummy arch]} {
- if {$arch != $mips_arch && $mips_forced_isa} {
- set matches 0
- }
- } elseif {[regexp -- {^-mips(.*)} $flag dummy isa]} {
+ } elseif {[regexp -- {^-mips(.*)} $flag dummy isa]
+ || [regexp -- {^-march=mips(.*)} $flag dummy isa]} {
if {![regexp {(.*)r(.*)} $isa dummy isa isa_rev]} {
set isa_rev 1
}
&& $mips_forced_isa} {
set matches 0
}
+ } elseif {[regexp -- {^-march=(.*)} $flag dummy arch]} {
+ if {$arch != $mips_arch && $mips_forced_isa} {
+ set matches 0
+ }
} elseif {[regexp -- {^-m(hard|soft)-float} $flag dummy float]} {
if {$mips_float != $float && $mips_forced_float} {
set matches 0
/* Test SB-1 v2sf extensions. */
/* { dg-do compile } */
-/* { dg-mips-options "-march=sb1 -O2 -mpaired-single -mhard-float -mgp64 -ffast-math" } */
+/* { dg-mips-options "-march=sb1 -O2 -mpaired-single -mgp64 -ffast-math" } */
/* { dg-final { scan-assembler "div.ps" } } */
/* { dg-final { scan-assembler "recip.ps" } } */
/* { dg-final { scan-assembler "sqrt.ps" } } */
} elseif { [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] } {
lappend vectorizer_options "-msse2"
set test_tree_vectorize 1
- } elseif { [istarget "mipsisa64*-*-*"]
+ } elseif { [istarget "mips*-*-*"]
&& [check_effective_target_mpaired_single]
&& [check_effective_target_nomips16] } {
lappend vectorizer_options "-mpaired-single"