UNSPEC_GET_FCSR
UNSPEC_SET_FCSR
+ ;; Floating-point unspecs.
+ UNSPEC_FMIN
+ UNSPEC_FMAX
+
;; HI/LO moves.
UNSPEC_MFHI
UNSPEC_MTHI
;; frsqrt floating point reciprocal square root
;; frsqrt1 floating point reciprocal square root step1
;; frsqrt2 floating point reciprocal square root step2
+;; fminmax floating point min/max
;; dspmac DSP MAC instructions not saturating the accumulator
;; dspmacsat DSP MAC instructions that saturate the accumulator
;; accext DSP accumulator extract instructions
prefetch,prefetchx,condmove,mtc,mfc,mthi,mtlo,mfhi,mflo,const,arith,logical,
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,dspmac,dspmacsat,accext,accmod,dspalu,dspalusat,
- multi,atomic,syncloop,nop,ghost,multimem,
+ frsqrt,frsqrt1,frsqrt2,fminmax,dspmac,dspmacsat,accext,accmod,dspalu,
+ dspalusat,multi,atomic,syncloop,nop,ghost,multimem,
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,
[(set_attr "move_type" "load")
(set_attr "insn_count" "2")])
+;;
+;; Float point MIN/MAX
+;;
+
+(define_insn "smin<mode>3"
+ [(set (match_operand:SCALARF 0 "register_operand" "=f")
+ (smin:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
+ (match_operand:SCALARF 2 "register_operand" "f")))]
+ "ISA_HAS_FMIN_FMAX"
+ "min.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fminmax")
+ (set_attr "mode" "<UNITMODE>")])
+
+(define_insn "smax<mode>3"
+ [(set (match_operand:SCALARF 0 "register_operand" "=f")
+ (smax:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
+ (match_operand:SCALARF 2 "register_operand" "f")))]
+ "ISA_HAS_FMIN_FMAX"
+ "max.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fminmax")
+ (set_attr "mode" "<UNITMODE>")])
+
+(define_insn "fmin<mode>3"
+ [(set (match_operand:SCALARF 0 "register_operand" "=f")
+ (unspec:SCALARF [(use (match_operand:SCALARF 1 "register_operand" "f"))
+ (use (match_operand:SCALARF 2 "register_operand" "f"))]
+ UNSPEC_FMIN))]
+ "ISA_HAS_FMIN_FMAX"
+ "min.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fminmax")
+ (set_attr "mode" "<UNITMODE>")])
+
+(define_insn "fmax<mode>3"
+ [(set (match_operand:SCALARF 0 "register_operand" "=f")
+ (unspec:SCALARF [(use (match_operand:SCALARF 1 "register_operand" "f"))
+ (use (match_operand:SCALARF 2 "register_operand" "f"))]
+ UNSPEC_FMAX))]
+ "ISA_HAS_FMIN_FMAX"
+ "max.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fminmax")
+ (set_attr "mode" "<UNITMODE>")])
;; 2 HI loads are joined.
(define_peephole2
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-mhard-float -fno-finite-math-only -march=mips32r6" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+/* Test MIN.D. */
+
+/* { dg-final { scan-assembler "\tmin\\.d\t" } } */
+double
+test01 (double x, double y)
+{
+ return __builtin_fmin (x, y);
+}
+
+/* Test MIN.S. */
+
+/* { dg-final { scan-assembler "\tmin\\.s\t" } } */
+float
+test02 (float x, float y)
+{
+ return __builtin_fminf (x, y);
+}
+
+/* Test MAX.D. */
+
+/* { dg-final { scan-assembler "\tmax\\.d\t" } } */
+double
+test03 (double x, double y)
+{
+ return __builtin_fmax (x, y);
+}
+
+/* Test MAX.S. */
+
+/* { dg-final { scan-assembler "\tmax\\.s\t" } } */
+float
+test04 (float x, float y)
+{
+ return __builtin_fmaxf (x, y);
+}
+
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-mhard-float -march=mips32r6" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+extern double fmin (double, double);
+extern double fmax (double, double);
+extern float fminf (float, float);
+extern float fmaxf (float, float);
+
+/* Test MIN.D. */
+
+/* { dg-final { scan-assembler "\tmin\\.d\t" } } */
+double test01 (double x, double y) {
+ return fmin (x, y);
+}
+
+/* Test MIN.S. */
+
+/* { dg-final { scan-assembler "\tmin\\.s\t" } } */
+float test02 (float x, float y) {
+ return fminf (x, y);
+}
+
+/* Test MAX.D. */
+
+/* { dg-final { scan-assembler "\tmax\\.d\t" } } */
+double test03 (double x, double y) {
+ return fmax (x, y);
+}
+
+/* Test MAX.S. */
+
+/* { dg-final { scan-assembler "\tmax\\.s\t" } } */
+float test04 (float x, float y) {
+ return fmaxf (x, y);
+}