[27/61] MIPSR6: Define new R6 FPU instructions

Message ID 20250131171232.1018281-29-aleksandar.rakic@htecgroup.com
State New
Headers
Series Improve Mips target |

Commit Message

Aleksandar Rakic Jan. 31, 2025, 5:13 p.m. UTC
  From: Matthew Fortune <matthew.fortune@imgtec.com>

gcc/
	* config/mips/mips.h (ISA_HAS_FCLASS): New macro.
	(ISA_HAS_RINT): Likewise.
	* config/mips/mips.md (unspec): Add UNSPEC_FCLASS and
	UNSPEC_FRINT.
	(type) Add fclass and frint.
	(fnma<mode>4): Enable for ISA_HAS_FUSED_MADDF.
	(fnma<mode>4_msubf): New define_insn.
	(fmax_a_<mode>): Likewise.
	(fmin_a_<mode>): Likewise.
	(fclass_<mode>): Likewise.
	(frint_<mode>): Likewise.
	* config/mips/i6400.md (i6400_fpu_minmax): Include
	fclass type.
	(i6400_fpu_fadd): Include frint type.
	* config/mips/p6600.md (p6600_fpu_fadd): Include frint type.
	(p6600_fpu_fabs): Include fclass type.

Cherry-picked bbc81087aa0e307aaf262021c40473644ed2a9b2
from https://github.com/MIPS/gcc

Signed-off-by: Matthew Fortune <matthew.fortune@imgtec.com>
Signed-off-by: Faraz Shahbazker <fshahbazker@wavecomp.com>
Signed-off-by: Aleksandar Rakic <aleksandar.rakic@htecgroup.com>
---
 gcc/config/mips/i6400.md |  6 ++--
 gcc/config/mips/mips.h   |  4 +++
 gcc/config/mips/mips.md  | 61 ++++++++++++++++++++++++++++++++++++++--
 gcc/config/mips/p6600.md |  4 +--
 4 files changed, 67 insertions(+), 8 deletions(-)
  

Patch

diff --git a/gcc/config/mips/i6400.md b/gcc/config/mips/i6400.md
index d6f691ee217..4a2361667abd 100644
--- a/gcc/config/mips/i6400.md
+++ b/gcc/config/mips/i6400.md
@@ -219,16 +219,16 @@ 
        (eq_attr "type" "fabs,fneg,fmove"))
   "i6400_fpu_short, i6400_fpu_apu")
 
-;; min, max
+;; min, max, min_a, max_a, class
 (define_insn_reservation "i6400_fpu_minmax" 2
   (and (eq_attr "cpu" "i6400")
-       (eq_attr "type" "fminmax"))
+       (eq_attr "type" "fminmax,fclass"))
   "i6400_fpu_short+i6400_fpu_logic")
 
 ;; fadd, fsub, fcvt
 (define_insn_reservation "i6400_fpu_fadd" 4
   (and (eq_attr "cpu" "i6400")
-       (eq_attr "type" "fadd,fcvt"))
+       (eq_attr "type" "fadd,fcvt,frint"))
   "i6400_fpu_long, i6400_fpu_apu")
 
 ;; fmul
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index b727074bf53..efd23a262f9 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1291,6 +1291,10 @@  struct mips_cpu_info {
 
 #define ISA_HAS_FMIN_FMAX	(mips_isa_rev >= 6)
 
+#define ISA_HAS_FCLASS		(mips_isa_rev >= 6)
+
+#define ISA_HAS_RINT		(mips_isa_rev >= 6)
+
 /* ISA has data indexed prefetch instructions.  This controls use of
    'prefx', along with TARGET_HARD_FLOAT and TARGET_DOUBLE_FLOAT.
    (prefx is a cop1x instruction, so can only be used if FP is
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 814692aecf1..7d27e7d4b20 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -102,6 +102,8 @@ 
   ;; Floating-point unspecs.
   UNSPEC_FMIN
   UNSPEC_FMAX
+  UNSPEC_FCLASS
+  UNSPEC_FRINT
 
   ;; HI/LO moves.
   UNSPEC_MFHI
@@ -395,7 +397,7 @@ 
    shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move,
    fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,
    frsqrt,frsqrt1,frsqrt2,fminmax,dspmac,dspmacsat,accext,accmod,dspalu,
-   dspalusat,multi,atomic,syncloop,nop,ghost,multimem,
+   dspalusat,multi,atomic,syncloop,nop,ghost,multimem,fclass,frint,
    simd_div,simd_fclass,simd_flog2,simd_fadd,simd_fcvt,simd_fmul,simd_fmadd,
    simd_fdiv,simd_bitins,simd_bitmov,simd_insert,simd_sld,simd_mul,simd_fcmp,
    simd_fexp2,simd_int_arith,simd_bit,simd_shift,simd_splat,simd_fill,
@@ -2656,8 +2658,9 @@ 
 	(fma:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand"))
 		  (match_operand:ANYF 2 "register_operand")
 		  (match_operand:ANYF 3 "register_operand")))]
-  "(ISA_HAS_FUSED_MADD3 || ISA_HAS_FUSED_MADD4)
-   && !HONOR_SIGNED_ZEROS (<MODE>mode)")
+  "((ISA_HAS_FUSED_MADD3 || ISA_HAS_FUSED_MADD4)
+    && !HONOR_SIGNED_ZEROS (<MODE>mode))
+   || ISA_HAS_FUSED_MADDF")
 
 (define_insn "*fnma<mode>4_nmsub3"
   [(set (match_operand:ANYF 0 "register_operand" "=f")
@@ -2679,6 +2682,16 @@ 
   [(set_attr "type" "fmadd")
    (set_attr "mode" "<UNITMODE>")])
 
+(define_insn "*fnma<mode>4_msubf"
+  [(set (match_operand:ANYF 0 "register_operand" "=f")
+	(fma: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_FUSED_MADDF"
+  "msubf.<fmt>\t%0,%1,%2"
+  [(set_attr "type" "fmadd")
+   (set_attr "mode" "<UNITMODE>")])
+
 ;; fnms is defined as: (fma (neg op1) op2 (neg op3))
 ;; ((-op1) * op2) - op3 ==> -(op1 * op2) - op3 ==> -((op1 * op2) + op3)
 ;; The mips nmadd instructions implement -((op1 * op2) + op3)
@@ -8156,6 +8169,48 @@ 
   [(set_attr "type" "fminmax")
   (set_attr "mode" "<UNITMODE>")])
 
+(define_insn "fmax_a_<mode>"
+  [(set (match_operand:SCALARF 0 "register_operand" "=f")
+	(if_then_else
+	   (gt (abs:SCALARF (match_operand:SCALARF 1 "register_operand" "f"))
+	       (abs:SCALARF (match_operand:SCALARF 2 "register_operand" "f")))
+	   (match_dup 1)
+	   (match_dup 2)))]
+  "ISA_HAS_FMIN_FMAX"
+  "maxa.<fmt>\t%0,%1,%2"
+  [(set_attr "type" "fminmax")
+   (set_attr "mode" "<UNITMODE>")])
+
+(define_insn "fmin_a_<mode>"
+  [(set (match_operand:SCALARF 0 "register_operand" "=f")
+	(if_then_else
+	   (lt (abs:SCALARF (match_operand:SCALARF 1 "register_operand" "f"))
+	       (abs:SCALARF (match_operand:SCALARF 2 "register_operand" "f")))
+	   (match_dup 1)
+	   (match_dup 2)))]
+  "ISA_HAS_FMIN_FMAX"
+  "mina.<fmt>\t%0,%1,%2"
+  [(set_attr "type" "fminmax")
+   (set_attr "mode" "<UNITMODE>")])
+
+(define_insn "fclass_<mode>"
+  [(set (match_operand:ANYF 0 "register_operand" "=f")
+	(unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")]
+			 UNSPEC_FCLASS))]
+  "ISA_HAS_FCLASS"
+  "fclass.<fmt>\t%0,%1"
+  [(set_attr "type" "fclass")
+   (set_attr "mode" "<UNITMODE>")])
+
+(define_insn "frint_<mode>"
+  [(set (match_operand:ANYF 0 "register_operand" "=f")
+	(unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")]
+		     UNSPEC_FRINT))]
+  "ISA_HAS_RINT"
+  "rint.<fmt>\t%0,%1"
+  [(set_attr "type" "frint")
+   (set_attr "mode" "<UNITMODE>")])
+
 ;; 2 HI loads are joined.
 (define_peephole2
   [(set (match_operand:SI 0 "register_operand")
diff --git a/gcc/config/mips/p6600.md b/gcc/config/mips/p6600.md
index b6cb554939a..2e229b50a59 100644
--- a/gcc/config/mips/p6600.md
+++ b/gcc/config/mips/p6600.md
@@ -164,13 +164,13 @@ 
 ;; fadd, fsub
 (define_insn_reservation "p6600_fpu_fadd" 4
   (and (eq_attr "cpu" "p6600")
-       (eq_attr "type" "fadd"))
+       (eq_attr "type" "fadd,frint"))
   "p6600_fpu_long, p6600_fpu_apu")
 
 ;; fabs, fneg, fcmp, fminmax
 (define_insn_reservation "p6600_fpu_fabs" 2
   (and (eq_attr "cpu" "p6600")
-       (ior (eq_attr "type" "fabs,fneg,fcmp,fmove,fminmax")
+       (ior (eq_attr "type" "fabs,fneg,fcmp,fmove,fclass,fminmax")
 	   (and (eq_attr "type" "condmove")
 		(eq_attr "mode" "SF,DF"))))
   "p6600_fpu_short, p6600_fpu_apu")