diff --git a/cranelift/filetests/isa/intel/binary32-float.cton b/cranelift/filetests/isa/intel/binary32-float.cton index 9358fc338e..bb1df58602 100644 --- a/cranelift/filetests/isa/intel/binary32-float.cton +++ b/cranelift/filetests/isa/intel/binary32-float.cton @@ -94,6 +94,17 @@ ebb0: ; asm: cvttss2si %xmm2, %esi [-,%rsi] v41 = x86_cvtt2si.i32 v11 ; bin: f3 0f 2c f2 + ; Min/max. + + ; asm: minss %xmm2, %xmm5 + [-,%xmm5] v42 = x86_fmin v10, v11 ; bin: f3 0f 5d ea + ; asm: minss %xmm5, %xmm2 + [-,%xmm2] v43 = x86_fmin v11, v10 ; bin: f3 0f 5d d5 + ; asm: maxss %xmm2, %xmm5 + [-,%xmm5] v44 = x86_fmax v10, v11 ; bin: f3 0f 5f ea + ; asm: maxss %xmm5, %xmm2 + [-,%xmm2] v45 = x86_fmax v11, v10 ; bin: f3 0f 5f d5 + ; Unary arithmetic. ; asm: sqrtss %xmm5, %xmm2 @@ -281,6 +292,17 @@ ebb0: ; asm: cvttsd2si %xmm2, %esi [-,%rsi] v41 = x86_cvtt2si.i32 v11 ; bin: f2 0f 2c f2 + ; Min/max. + + ; asm: minsd %xmm2, %xmm5 + [-,%xmm5] v42 = x86_fmin v10, v11 ; bin: f2 0f 5d ea + ; asm: minsd %xmm5, %xmm2 + [-,%xmm2] v43 = x86_fmin v11, v10 ; bin: f2 0f 5d d5 + ; asm: maxsd %xmm2, %xmm5 + [-,%xmm5] v44 = x86_fmax v10, v11 ; bin: f2 0f 5f ea + ; asm: maxsd %xmm5, %xmm2 + [-,%xmm2] v45 = x86_fmax v11, v10 ; bin: f2 0f 5f d5 + ; Unary arithmetic. ; asm: sqrtsd %xmm5, %xmm2 diff --git a/cranelift/filetests/isa/intel/binary64-float.cton b/cranelift/filetests/isa/intel/binary64-float.cton index 5763a5ab67..2156ebc5db 100644 --- a/cranelift/filetests/isa/intel/binary64-float.cton +++ b/cranelift/filetests/isa/intel/binary64-float.cton @@ -108,6 +108,17 @@ ebb0: ; asm: cvttss2si %xmm10, %rsi [-,%rsi] v43 = x86_cvtt2si.i64 v11 ; bin: f3 49 0f 2c f2 + ; Min/max. + + ; asm: minss %xmm10, %xmm5 + [-,%xmm5] v44 = x86_fmin v10, v11 ; bin: f3 41 0f 5d ea + ; asm: minss %xmm5, %xmm10 + [-,%xmm10] v45 = x86_fmin v11, v10 ; bin: f3 44 0f 5d d5 + ; asm: maxss %xmm10, %xmm5 + [-,%xmm5] v46 = x86_fmax v10, v11 ; bin: f3 41 0f 5f ea + ; asm: maxss %xmm5, %xmm10 + [-,%xmm10] v47 = x86_fmax v11, v10 ; bin: f3 44 0f 5f d5 + ; Unary arithmetic. ; asm: sqrtss %xmm5, %xmm10 @@ -315,6 +326,17 @@ ebb0: ; asm: cvttsd2si %xmm10, %rsi [-,%rsi] v43 = x86_cvtt2si.i64 v11 ; bin: f2 49 0f 2c f2 + ; Min/max. + + ; asm: minsd %xmm10, %xmm5 + [-,%xmm5] v44 = x86_fmin v10, v11 ; bin: f2 41 0f 5d ea + ; asm: minsd %xmm5, %xmm10 + [-,%xmm10] v45 = x86_fmin v11, v10 ; bin: f2 44 0f 5d d5 + ; asm: maxsd %xmm10, %xmm5 + [-,%xmm5] v46 = x86_fmax v10, v11 ; bin: f2 41 0f 5f ea + ; asm: maxsd %xmm5, %xmm10 + [-,%xmm10] v47 = x86_fmax v11, v10 ; bin: f2 44 0f 5f d5 + ; Unary arithmetic. ; asm: sqrtsd %xmm5, %xmm10 diff --git a/lib/cretonne/meta/isa/intel/encodings.py b/lib/cretonne/meta/isa/intel/encodings.py index 9eb832572d..c647d5bf28 100644 --- a/lib/cretonne/meta/isa/intel/encodings.py +++ b/lib/cretonne/meta/isa/intel/encodings.py @@ -398,7 +398,9 @@ for inst, opc in [ (base.fadd, 0x58), (base.fsub, 0x5c), (base.fmul, 0x59), - (base.fdiv, 0x5e)]: + (base.fdiv, 0x5e), + (x86.fmin, 0x5d), + (x86.fmax, 0x5f)]: enc_flt(inst.f32, r.frm, 0xf3, 0x0f, opc) enc_flt(inst.f64, r.frm, 0xf2, 0x0f, opc) diff --git a/lib/cretonne/meta/isa/intel/instructions.py b/lib/cretonne/meta/isa/intel/instructions.py index c9739ccecb..27a0063557 100644 --- a/lib/cretonne/meta/isa/intel/instructions.py +++ b/lib/cretonne/meta/isa/intel/instructions.py @@ -69,4 +69,34 @@ cvtt2si = Instruction( """, ins=x, outs=a) +x = Operand('x', Float) +a = Operand('a', Float) +y = Operand('y', Float) + +fmin = Instruction( + 'x86_fmin', r""" + Floating point minimum with Intel semantics. + + This is equivalent to the C ternary operator `x < y ? x : y` which + differs from :inst:`fmin` when either operand is NaN or when comparing + +0.0 to -0.0. + + When the two operands don't compare as LT, `y` is returned unchanged, + even if it is a signalling NaN. + """, + ins=(x, y), outs=a) + +fmax = Instruction( + 'x86_fmax', r""" + Floating point maximum with Intel semantics. + + This is equivalent to the C ternary operator `x > y ? x : y` which + differs from :inst:`fmax` when either operand is NaN or when comparing + +0.0 to -0.0. + + When the two operands don't compare as GT, `y` is returned unchanged, + even if it is a signalling NaN. + """, + ins=(x, y), outs=a) + GROUP.close()