Browse Source

+ added explanation for min/max intrinsics
* prepared x86 implementation for proper NaN handling

git-svn-id: trunk@47715 -

florian 4 năm trước cách đây
mục cha
commit
674c3f04e0
2 tập tin đã thay đổi với 20 bổ sung1 xóa
  1. 11 0
      compiler/compinnr.pas
  2. 9 1
      compiler/x86/nx86inl.pas

+ 11 - 0
compiler/compinnr.pas

@@ -153,6 +153,17 @@ type
      in_fma_double       = 134,
      in_fma_extended     = 135,
      in_fma_float128     = 136,
+
+     { the min/max intrinsics must follow the x86 sse
+       behaviour of min/max regarding handling
+       NaN: in case of a NaN the result is always the second
+       operand. This allows a simple translation of
+       if a>b then result:=a else result:=b;
+       statements into these intrinsics
+
+       The min/max intrinsics are not supposed to
+       be exposed to the user but only
+       used internally by the compiler/optimizer }
      in_max_single       = 137,
      in_max_double       = 138,
      in_min_single       = 139,

+ 9 - 1
compiler/x86/nx86inl.pas

@@ -1479,6 +1479,14 @@ implementation
                    end;
                end;
 
+             { due to min/max behaviour that it loads always the second operand (must be the else assignment) into destination if
+               one of the operands is a NaN, we cannot swap operands to omit a mova operation in case fastmath is off }
+             if not(cs_opt_fastmath in current_settings.optimizerswitches) and gotmem and (memop=1) then
+               begin
+                 hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,paraarray[1].location,paraarray[1].resultdef,true);
+                 gotmem:=false;
+               end;
+
              op:=oparray[inlinenumber in [in_max_single,in_max_double],UseAVX,tfloatdef(resultdef).floattype];
 
              location_reset(location,LOC_MMREGISTER,paraarray[1].location.size);
@@ -1521,7 +1529,7 @@ implementation
                begin
                  if UseAVX then
                    emit_reg_reg_reg(op,S_NO,
-                     paraarray[1].location.register,paraarray[2].location.register,location.register)
+                     paraarray[2].location.register,paraarray[1].location.register,location.register)
                  else
                    begin
                      hlcg.a_loadmm_reg_reg(current_asmdata.CurrAsmList,paraarray[1].resultdef,resultdef,