This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[MIPS][LS2][3/5] Miscellaneous instructions
- From: Maxim Kuvyrkov <maxim at codesourcery dot com>
- To: Richard Sandiford <rsandifo at nildram dot co dot uk>
- Cc: gcc-patches <gcc-patches at gcc dot gnu dot org>, Zhang Le <r0bertz at gentoo dot org>, Eric Fisher <joefoxreal at gmail dot com>
- Date: Thu, 22 May 2008 21:52:40 +0400
- Subject: [MIPS][LS2][3/5] Miscellaneous instructions
- References: <4835A9B4.9000709@codesourcery.com>
This patch adds support for several non-MIPS 3 instructions ST Loongson
2E/2F CPUs support.
Generally, Loongson is a MIPS3 core, but it also supports
* movn/movz for integer modes
* [n]madd/[n]msub instructions, which are analogues of respective
instructions from MIPS4 ISA.
* A subset of paired-single float instructions of MIPS5 ISA.
Support for first two items is pretty straightforward.
To add support for Loongson paired-single float instructions the
following was done.
To select the subset of paired-single float instructions Loongson
supports new macro TARGET_PAIRED_SINGLE_FLOAT_MIPS5_LS2 and
mode_iterator ANYF_MIPS5_LS2 were declared.
MIPS5 .ps instructions are described with help of mode_iterator ANYF in
mips.md:
;; This mode macro allows :ANYF to be used wherever a scalar or vector
;; floating-point mode is allowed.
(define_mode_iterator ANYF
[(SF "TARGET_HARD_FLOAT")
(DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
(V2SF "TARGET_PAIRED_SINGLE_FLOAT")])
To facilitate declaration of .ps instructions for Loongson2 I introduced
one more target mask MASK_PAIRED_SINGLE_FLOAT_MIPS5_LS2 which is set
whenever TARGET_PAIRED_SINGLE_FLOAT of TARGET_LOONGSON_2EF is set.
Then I used ANYF_MIPS5_LS2 mode_iterator (see below) to describe
instructions both MIPS5 and Loongson support and ANYF mode_macro to
describe those which only MIPS5 ISA has.
;; This mode macro allows :ANYF_MIPS5_LS2 to be used wherever
;; a scalar or Loongson2 vector floating-point mode is allowed.
(define_mode_macro ANYF_MIPS5_LS2
[(SF "TARGET_HARD_FLOAT")
(DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
(V2SF "TARGET_PAIRED_SINGLE_FLOAT_MIPS5_LS2")])
Hence the instructions from MIPS5 ISA, which happen to be supported by
Loongson2, are declared with ANYF_MIPS5_LS2 mode_iterator. I don't like
this, but can't figure out alternative way to name / describe these
instructions.
OK for trunk?
Thanks,
Maxim Kuvyrkov
CodeSourcery
2008-05-22 Maxim Kuvyrkov <maxim@codesourcery.com>
* config/mips/mips.h (ISA_HAS_CONDMOVE): Slice ISA_HAS_FP_CONDMOVE
from it.
(ISA_HAS_FP_CONDMOVE): New macro.
(ISA_HAS_FP_MADD4_MSUB4, ISA_HAS_FP_MADD3_MSUB3): New macros.
(ISA_HAS_NMADD_NMSUB): Rename to ISA_HAS_NMADD4_NMSUB4.
(ISA_HAS_NMADD3_NMSUB3): New macro.
* config/mips/mips.opt (mpaired-single-loongson2): New machine-specific
option.
* doc/invoke.texi: Document it.
* config/mips/mips.c (mips_rtx_costs): Update.
(override_options): Enable paired-single float instructions when
compiling for ST Loongson 2E/2F.
(mips_vector_mode_supported_p): Update.
* config/mips/mips-ps-3d.md (mips_abs_ps, mips_c_cond_ps, s<cond>_ps):
Use patterns when compiling for ST Loongson 2E/2F.
* config/mips/mips.md (MOVECC): Don't use FP conditional moves when
compiling for ST Loongson 2E/2F.
(ANYF_MIPS5_LS2): New mode macro to use instead of ANYF when insn
is eligible for either MIPS5 or ST Loongson 2E/2F.
(add<mode>3, sub<mode>3): Use ANYF_MIPS5_LS2 instead of ANYF.
(mulv2sf3): Use insn when compiling for ST Loongson 2E/2F.
(madd<mode>): Rename to madd4<mode>. Update.
(madd3<mode>): New pattern.
(msub<mode>): Rename to msub4<mode>. Update.
(msub3<mode>): New pattern.
(nmadd<mode>): Rename to nmadd4<mode>. Update.
(nmadd3<mode>): New pattern.
(nmadd<mode>_fastmath): Rename to nmadd4<mode>_fastmath. Update.
(nmadd3<mode>_fastmath): New pattern.
(nmsub<mode>): Rename to nmsub4<mode>. Update.
(nmsub3<mode>): New pattern.
(nmsub<mode>_fastmath): Rename to nmsub4<mode>_fastmath. Update.
(nmsub3<mode>_fastmath): New pattern.
(abs<mode>2, neg<mode>2): Use ANYF_MIPS5_LS2 instead of ANYF.
(movv2sf_hardfloat_64bit, movv2sf_hardfloat_32bit): Use insns when
compiling for ST Loongson 2E/2F.
(mov<SCALARF:mode>_on_<MOVECC:mode>, mov<mode>cc): Update.
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi (revision 64)
+++ gcc/doc/invoke.texi (working copy)
@@ -12205,6 +12205,16 @@ Use (do not use) paired-single floating-
@xref{MIPS Paired-Single Support}. This option requires
hardware floating-point support to be enabled.
+@item -mpaired-single-loongson2
+@itemx -mno-paired-single-loongson2
+@opindex mpaired-single-loongson2
+@opindex mno-paired-single-loongson2
+Use (do not use) paired-single floating-point instructions of
+ST Loongson 2E/2F CPUs.
+@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. !!! This should be fixed by NathanS' patch.
+
@item -mdmx
@itemx -mno-mdmx
@opindex mdmx
Index: gcc/config/mips/mips-ps-3d.md
===================================================================
--- gcc/config/mips/mips-ps-3d.md (revision 64)
+++ gcc/config/mips/mips-ps-3d.md (working copy)
@@ -295,7 +295,7 @@
[(set (match_operand:V2SF 0 "register_operand" "=f")
(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")]
UNSPEC_ABS_PS))]
- "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
+ "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT_MIPS5_LS2"
"abs.ps\t%0,%1"
[(set_attr "type" "fabs")
(set_attr "mode" "SF")])
@@ -389,7 +389,7 @@
(match_operand:V2SF 2 "register_operand" "f")
(match_operand 3 "const_int_operand" "")]
UNSPEC_C))]
- "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
+ "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT_MIPS5_LS2"
"c.%Y3.ps\t%0,%1,%2"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")])
@@ -416,7 +416,7 @@
[(fcond (match_operand:V2SF 1 "register_operand" "f")
(match_operand:V2SF 2 "register_operand" "f"))]
UNSPEC_SCC))]
- "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
+ "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT_MIPS5_LS2"
"c.<fcond>.ps\t%0,%1,%2"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")])
@@ -427,7 +427,7 @@
[(swapped_fcond (match_operand:V2SF 1 "register_operand" "f")
(match_operand:V2SF 2 "register_operand" "f"))]
UNSPEC_SCC))]
- "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
+ "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT_MIPS5_LS2"
"c.<swapped_fcond>.ps\t%0,%2,%1"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")])
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md (revision 64)
+++ gcc/config/mips/mips.md (working copy)
@@ -512,7 +512,8 @@
;; This mode iterator allows :MOVECC to be used anywhere that a
;; conditional-move-type condition is needed.
-(define_mode_iterator MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
+(define_mode_iterator MOVECC [SI (DI "TARGET_64BIT")
+ (CC "TARGET_HARD_FLOAT && !TARGET_LOONGSON_2EF")])
;; 64-bit modes for which we provide move patterns.
(define_mode_iterator MOVE64
@@ -534,6 +535,13 @@
(DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
(V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")])
+;; This mode iterator allows :ANYF_MIPS5_LS2 to be used wherever a scalar
+;; or MIPS5 / Loongson2 vector floating-point mode is allowed.
+(define_mode_iterator ANYF_MIPS5_LS2
+ [(SF "TARGET_HARD_FLOAT")
+ (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
+ (V2SF "TARGET_PAIRED_SINGLE_FLOAT_MIPS5_LS2")])
+
;; Like ANYF, but only applies to scalar modes.
(define_mode_iterator SCALARF [(SF "TARGET_HARD_FLOAT")
(DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
@@ -831,9 +839,10 @@
;;
(define_insn "add<mode>3"
- [(set (match_operand:ANYF 0 "register_operand" "=f")
- (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
- (match_operand:ANYF 2 "register_operand" "f")))]
+ [(set (match_operand:ANYF_MIPS5_LS2 0 "register_operand" "=f")
+ (plus:ANYF_MIPS5_LS2
+ (match_operand:ANYF_MIPS5_LS2 1 "register_operand" "f")
+ (match_operand:ANYF_MIPS5_LS2 2 "register_operand" "f")))]
""
"add.<fmt>\t%0,%1,%2"
[(set_attr "type" "fadd")
@@ -1049,9 +1058,10 @@
;;
(define_insn "sub<mode>3"
- [(set (match_operand:ANYF 0 "register_operand" "=f")
- (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
- (match_operand:ANYF 2 "register_operand" "f")))]
+ [(set (match_operand:ANYF_MIPS5_LS2 0 "register_operand" "=f")
+ (minus:ANYF_MIPS5_LS2
+ (match_operand:ANYF_MIPS5_LS2 1 "register_operand" "f")
+ (match_operand:ANYF_MIPS5_LS2 2 "register_operand" "f")))]
""
"sub.<fmt>\t%0,%1,%2"
[(set_attr "type" "fadd")
@@ -1118,7 +1128,7 @@
[(set (match_operand:V2SF 0 "register_operand" "=f")
(mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
(match_operand:V2SF 2 "register_operand" "f")))]
- "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
+ "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT_MIPS5_LS2"
"mul.ps\t%0,%1,%2"
[(set_attr "type" "fmul")
(set_attr "mode" "SF")])
@@ -1898,33 +1908,55 @@
;; Floating point multiply accumulate instructions.
-(define_insn "*madd<mode>"
+(define_insn "*madd4<mode>"
[(set (match_operand:ANYF 0 "register_operand" "=f")
(plus:ANYF (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_FP4 && TARGET_FUSED_MADD"
+ "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD"
"madd.<fmt>\t%0,%3,%1,%2"
[(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")])
-(define_insn "*msub<mode>"
+(define_insn "*madd3<mode>"
+ [(set (match_operand:ANYF 0 "register_operand" "=f")
+ (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
+ (match_operand:ANYF 2 "register_operand" "f"))
+ (match_operand:ANYF 3 "register_operand" "0")))]
+ "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD
+ && !HONOR_NANS (<MODE>mode)"
+ "madd.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fmadd")
+ (set_attr "mode" "<UNITMODE>")])
+
+(define_insn "*msub4<mode>"
[(set (match_operand:ANYF 0 "register_operand" "=f")
(minus:ANYF (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_FP4 && TARGET_FUSED_MADD"
+ "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD"
"msub.<fmt>\t%0,%3,%1,%2"
[(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")])
-(define_insn "*nmadd<mode>"
+(define_insn "*msub3<mode>"
+ [(set (match_operand:ANYF 0 "register_operand" "=f")
+ (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
+ (match_operand:ANYF 2 "register_operand" "f"))
+ (match_operand:ANYF 3 "register_operand" "0")))]
+ "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD
+ && !HONOR_NANS (<MODE>mode)"
+ "msub.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fmadd")
+ (set_attr "mode" "<UNITMODE>")])
+
+(define_insn "*nmadd4<mode>"
[(set (match_operand:ANYF 0 "register_operand" "=f")
(neg:ANYF (plus:ANYF
(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 (<MODE>mode)
+ "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode)
&& TARGET_FUSED_MADD
&& HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
@@ -1932,13 +1964,27 @@
[(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")])
-(define_insn "*nmadd<mode>_fastmath"
+(define_insn "*nmadd3<mode>"
+ [(set (match_operand:ANYF 0 "register_operand" "=f")
+ (neg:ANYF (plus:ANYF
+ (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
+ (match_operand:ANYF 2 "register_operand" "f"))
+ (match_operand:ANYF 3 "register_operand" "0"))))]
+ "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode)
+ && TARGET_FUSED_MADD
+ && HONOR_SIGNED_ZEROS (<MODE>mode)
+ && !HONOR_NANS (<MODE>mode)"
+ "nmadd.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fmadd")
+ (set_attr "mode" "<UNITMODE>")])
+
+(define_insn "*nmadd4<mode>_fastmath"
[(set (match_operand:ANYF 0 "register_operand" "=f")
(minus:ANYF
(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 (<MODE>mode)
+ "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode)
&& TARGET_FUSED_MADD
&& !HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
@@ -1946,13 +1992,27 @@
[(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")])
-(define_insn "*nmsub<mode>"
+(define_insn "*nmadd3<mode>_fastmath"
+ [(set (match_operand:ANYF 0 "register_operand" "=f")
+ (minus:ANYF
+ (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
+ (match_operand:ANYF 2 "register_operand" "f"))
+ (match_operand:ANYF 3 "register_operand" "0")))]
+ "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode)
+ && TARGET_FUSED_MADD
+ && !HONOR_SIGNED_ZEROS (<MODE>mode)
+ && !HONOR_NANS (<MODE>mode)"
+ "nmadd.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fmadd")
+ (set_attr "mode" "<UNITMODE>")])
+
+(define_insn "*nmsub4<mode>"
[(set (match_operand:ANYF 0 "register_operand" "=f")
(neg:ANYF (minus:ANYF
(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 (<MODE>mode)
+ "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode)
&& TARGET_FUSED_MADD
&& HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
@@ -1960,19 +2020,47 @@
[(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")])
-(define_insn "*nmsub<mode>_fastmath"
+(define_insn "*nmsub3<mode>"
+ [(set (match_operand:ANYF 0 "register_operand" "=f")
+ (neg:ANYF (minus:ANYF
+ (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
+ (match_operand:ANYF 3 "register_operand" "f"))
+ (match_operand:ANYF 1 "register_operand" "0"))))]
+ "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode)
+ && TARGET_FUSED_MADD
+ && HONOR_SIGNED_ZEROS (<MODE>mode)
+ && !HONOR_NANS (<MODE>mode)"
+ "nmsub.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fmadd")
+ (set_attr "mode" "<UNITMODE>")])
+
+(define_insn "*nmsub4<mode>_fastmath"
[(set (match_operand:ANYF 0 "register_operand" "=f")
(minus:ANYF
(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 (<MODE>mode)
+ "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode)
&& TARGET_FUSED_MADD
&& !HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
"nmsub.<fmt>\t%0,%1,%2,%3"
[(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")])
+
+(define_insn "*nmsub3<mode>_fastmath"
+ [(set (match_operand:ANYF 0 "register_operand" "=f")
+ (minus:ANYF
+ (match_operand:ANYF 1 "register_operand" "f")
+ (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
+ (match_operand:ANYF 3 "register_operand" "0"))))]
+ "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode)
+ && TARGET_FUSED_MADD
+ && !HONOR_SIGNED_ZEROS (<MODE>mode)
+ && !HONOR_NANS (<MODE>mode)"
+ "nmsub.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fmadd")
+ (set_attr "mode" "<UNITMODE>")])
;;
;; ....................
@@ -2145,8 +2233,9 @@
;; abs.fmt if the signs of NaNs matter.
(define_insn "abs<mode>2"
- [(set (match_operand:ANYF 0 "register_operand" "=f")
- (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
+ [(set (match_operand:ANYF_MIPS5_LS2 0 "register_operand" "=f")
+ (abs:ANYF_MIPS5_LS2
+ (match_operand:ANYF_MIPS5_LS2 1 "register_operand" "f")))]
"!HONOR_NANS (<MODE>mode)"
"abs.<fmt>\t%0,%1"
[(set_attr "type" "fabs")
@@ -2201,8 +2290,9 @@
;; neg.fmt if the signs of NaNs matter.
(define_insn "neg<mode>2"
- [(set (match_operand:ANYF 0 "register_operand" "=f")
- (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
+ [(set (match_operand:ANYF_MIPS5_LS2 0 "register_operand" "=f")
+ (neg:ANYF_MIPS5_LS2
+ (match_operand:ANYF_MIPS5_LS2 1 "register_operand" "f")))]
"!HONOR_NANS (<MODE>mode)"
"neg.<fmt>\t%0,%1"
[(set_attr "type" "fneg")
@@ -4147,7 +4237,7 @@
(define_expand "movv2sf"
[(set (match_operand:V2SF 0)
(match_operand:V2SF 1))]
- "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
+ "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT_MIPS5_LS2"
{
if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
DONE;
@@ -4157,7 +4247,7 @@
[(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_PAIRED_SINGLE_FLOAT_MIPS5_LS2
&& TARGET_64BIT
&& (register_operand (operands[0], V2SFmode)
|| reg_or_0_operand (operands[1], V2SFmode))"
@@ -4170,7 +4260,7 @@
[(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_PAIRED_SINGLE_FLOAT_MIPS5_LS2
&& !TARGET_64BIT
&& (register_operand (operands[0], V2SFmode)
|| reg_or_0_operand (operands[1], V2SFmode))"
@@ -6274,7 +6364,7 @@
(const_int 0)])
(match_operand:SCALARF 2 "register_operand" "f,0")
(match_operand:SCALARF 3 "register_operand" "0,f")))]
- "ISA_HAS_CONDMOVE"
+ "ISA_HAS_FP_CONDMOVE"
"@
mov%T4.<fmt>\t%0,%2,%1
mov%t4.<fmt>\t%0,%3,%1"
@@ -6301,7 +6391,7 @@
(if_then_else:SCALARF (match_dup 5)
(match_operand:SCALARF 2 "register_operand")
(match_operand:SCALARF 3 "register_operand")))]
- "ISA_HAS_CONDMOVE"
+ "ISA_HAS_FP_CONDMOVE"
{
mips_expand_conditional_move (operands);
DONE;
Index: gcc/config/mips/mips.opt
===================================================================
--- gcc/config/mips/mips.opt (revision 64)
+++ gcc/config/mips/mips.opt (working copy)
@@ -232,6 +232,10 @@ mpaired-single
Target Report Mask(PAIRED_SINGLE_FLOAT)
Use paired-single floating-point instructions
+mpaired-single-loongson2
+Target Report Mask(PAIRED_SINGLE_FLOAT_MIPS5_LS2)
+Use paired-single floating-point instructions of ST Loongson2 2E/2F CPUs
+
mshared
Target Report Var(TARGET_SHARED) Init(1)
When generating -mabicalls code, make the code suitable for use in shared libraries
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c (revision 64)
+++ gcc/config/mips/mips.c (working copy)
@@ -3229,7 +3229,7 @@ mips_rtx_costs (rtx x, int code, int out
case MINUS:
if (float_mode_p
- && ISA_HAS_NMADD_NMSUB (mode)
+ && (ISA_HAS_NMADD4_NMSUB4 (mode) || ISA_HAS_NMADD3_NMSUB3 (mode))
&& TARGET_FUSED_MADD
&& !HONOR_NANS (mode)
&& !HONOR_SIGNED_ZEROS (mode))
@@ -3280,7 +3280,7 @@ mips_rtx_costs (rtx x, int code, int out
case NEG:
if (float_mode_p
- && ISA_HAS_NMADD_NMSUB (mode)
+ && (ISA_HAS_NMADD4_NMSUB4 (mode) || ISA_HAS_NMADD3_NMSUB3 (mode))
&& TARGET_FUSED_MADD
&& !HONOR_NANS (mode)
&& HONOR_SIGNED_ZEROS (mode))
@@ -9204,7 +9204,7 @@ mips_vector_mode_supported_p (enum machi
switch (mode)
{
case V2SFmode:
- return TARGET_PAIRED_SINGLE_FLOAT;
+ return TARGET_PAIRED_SINGLE_FLOAT_MIPS5_LS2;
case V2HImode:
case V4QImode:
@@ -12573,6 +12573,11 @@ mips_override_options (void)
if (TARGET_MIPS3D)
target_flags |= MASK_PAIRED_SINGLE_FLOAT;
+ /* If TARGET_PAIRED_SINGLE_FLOAT or HAVE_LOONGSON_VECTOR_MODES,
+ enable MIPS5 / Loongson2 *.ps instructions. */
+ if (TARGET_PAIRED_SINGLE_FLOAT || HAVE_LOONGSON_VECTOR_MODES)
+ target_flags |= MASK_PAIRED_SINGLE_FLOAT_MIPS5_LS2;
+
/* Make sure that when TARGET_PAIRED_SINGLE_FLOAT is true, TARGET_FLOAT64
and TARGET_HARD_FLOAT_ABI are both true. */
if (TARGET_PAIRED_SINGLE_FLOAT && !(TARGET_FLOAT64 && TARGET_HARD_FLOAT_ABI))
Index: gcc/config/mips/mips.h
===================================================================
--- gcc/config/mips/mips.h (revision 64)
+++ gcc/config/mips/mips.h (working copy)
@@ -741,14 +741,19 @@ enum mips_code_readable_setting {
|| ISA_MIPS64) \
&& !TARGET_MIPS16)
-/* ISA has the conditional move instructions introduced in mips4. */
-#define ISA_HAS_CONDMOVE ((ISA_MIPS4 \
+/* ISA has the floating-point conditional move instructions introduced
+ in mips4. */
+#define ISA_HAS_FP_CONDMOVE ((ISA_MIPS4 \
|| ISA_MIPS32 \
|| ISA_MIPS32R2 \
|| ISA_MIPS64) \
&& !TARGET_MIPS5500 \
&& !TARGET_MIPS16)
+/* ISA has the integer conditional move instructions introduced in mips4 and
+ ST Loongson 2E/2F. */
+#define ISA_HAS_CONDMOVE (ISA_HAS_FP_CONDMOVE || TARGET_LOONGSON_2EF)
+
/* ISA has LDC1 and SDC1. */
#define ISA_HAS_LDC1_SDC1 (!ISA_MIPS1 && !TARGET_MIPS16)
@@ -783,14 +788,28 @@ enum mips_code_readable_setting {
/* 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 for mode MODE. */
-#define ISA_HAS_NMADD_NMSUB(MODE) \
+/* ISA has floating-point madd and msub instructions 'd = a * b [+-] c'. */
+#define ISA_HAS_FP_MADD4_MSUB4 ISA_HAS_FP4
+
+/* ISA has floating-point madd and msub instructions 'c [+-]= a * b'. */
+#define ISA_HAS_FP_MADD3_MSUB3 (TARGET_LOONGSON_2EF \
+ && !ISA_HAS_FP_MADD4_MSUB4)
+
+/* ISA has floating-point nmadd and nmsub instructions
+ 'd = -(a * b) [+-] c'. */
+#define ISA_HAS_NMADD4_NMSUB4(MODE) \
((ISA_MIPS4 \
|| (ISA_MIPS32R2 && (MODE) == V2SFmode) \
|| ISA_MIPS64) \
&& (!TARGET_MIPS5400 || TARGET_MAD) \
&& !TARGET_MIPS16)
+/* ISA has floating-point nmadd and nmsub instructions
+ 'c = -(a * b) [+-] c'. */
+#define ISA_HAS_NMADD3_NMSUB3(MODE) \
+ (TARGET_LOONGSON_2EF \
+ && !ISA_HAS_NMADD4_NMSUB4 (MODE))
+
/* ISA has count leading zeroes/ones instruction (not implemented). */
#define ISA_HAS_CLZ_CLO ((ISA_MIPS32 \
|| ISA_MIPS32R2 \