From: Matthew Fortune <matthew.fort...@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.fort...@imgtec.com> Signed-off-by: Faraz Shahbazker <fshahbaz...@wavecomp.com> Signed-off-by: Aleksandar Rakic <aleksandar.ra...@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(-) 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") -- 2.34.1