Browse Source

* fixed floating point precision conversions for loc_mmregister and
between loc_fpuregister and loc_mmregister

git-svn-id: trunk@5942 -

Jonas Maebe 18 years ago
parent
commit
fc99b0ad48
2 changed files with 26 additions and 30 deletions
  1. 24 14
      compiler/ncgcnv.pas
  2. 2 16
      compiler/x86/cgx86.pas

+ 24 - 14
compiler/ncgcnv.pas

@@ -272,22 +272,25 @@ interface
 
 
     procedure tcgtypeconvnode.second_real_to_real;
     procedure tcgtypeconvnode.second_real_to_real;
       begin
       begin
-         location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
+         location_reset(location,expectloc,def_cgsize(resultdef));
 {$ifdef x86}
 {$ifdef x86}
          { extended types in memory which should be loaded into the sse unit
          { extended types in memory which should be loaded into the sse unit
            must be converted by the fpu first, so force them to be loaded into
            must be converted by the fpu first, so force them to be loaded into
            the fpu }
            the fpu }
          if (expectloc=LOC_MMREGISTER) and
          if (expectloc=LOC_MMREGISTER) and
-           (left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) and
-           (left.location.size=OS_F80) then
-           location_force_fpureg(current_asmdata.CurrAsmList,left.location,false);
+            (left.location.size in [OS_F80,OS_C64]) then
+           begin
+             if (left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
+               location_force_fpureg(current_asmdata.CurrAsmList,left.location,false);
+             { round them down to the proper precision }
+             cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,left.location.size,location.size,left.location.register,left.location.register);
+             left.location.size:=location.size;
+           end;
 {$endif x86}
 {$endif x86}
          case left.location.loc of
          case left.location.loc of
             LOC_FPUREGISTER,
             LOC_FPUREGISTER,
             LOC_CFPUREGISTER:
             LOC_CFPUREGISTER:
               begin
               begin
-                location_copy(location,left.location);
-                location.size:=def_cgsize(resultdef);
                 case expectloc of
                 case expectloc of
                   LOC_FPUREGISTER:
                   LOC_FPUREGISTER:
                     begin
                     begin
@@ -298,7 +301,11 @@ interface
                       cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,left.location.size,location.size,left.location.register,location.register);
                       cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,left.location.size,location.size,left.location.register,location.register);
                     end;
                     end;
                   LOC_MMREGISTER:
                   LOC_MMREGISTER:
-                    location_force_mmregscalar(current_asmdata.CurrAsmList,location,false);
+                    begin
+                      location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,false);
+                      location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
+                      cg.a_loadmm_reg_reg(current_asmdata.CurrAsmList,left.location.size,location.size,left.location.register,location.register,nil);
+                    end
                   else
                   else
                     internalerror(2003012262);
                     internalerror(2003012262);
                 end;
                 end;
@@ -309,29 +316,32 @@ interface
               begin
               begin
                  if expectloc=LOC_MMREGISTER then
                  if expectloc=LOC_MMREGISTER then
                    begin
                    begin
-                     location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef));
                      location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
                      location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
                      cg.a_loadmm_loc_reg(current_asmdata.CurrAsmList,location.size,left.location,location.register,mms_movescalar)
                      cg.a_loadmm_loc_reg(current_asmdata.CurrAsmList,location.size,left.location,location.register,mms_movescalar)
                    end
                    end
                   else
                   else
                     begin
                     begin
-                      location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,left.location.size);
-                      cg.a_loadfpu_loc_reg(current_asmdata.CurrAsmList,location.size,left.location,location.register);
+                      location_force_fpureg(current_asmdata.CurrAsmList,left.location,false);
+                      location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
+                      cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,left.location.size,location.size,left.location.register,location.register);
                     end;
                     end;
                  location_freetemp(current_asmdata.CurrAsmList,left.location);
                  location_freetemp(current_asmdata.CurrAsmList,left.location);
               end;
               end;
             LOC_MMREGISTER,
             LOC_MMREGISTER,
             LOC_CMMREGISTER:
             LOC_CMMREGISTER:
               begin
               begin
-                location_copy(location,left.location);
                 case expectloc of
                 case expectloc of
                   LOC_FPUREGISTER:
                   LOC_FPUREGISTER:
                     begin
                     begin
-                      location_force_fpureg(current_asmdata.CurrAsmList,location,false);
-                      location.size:=def_cgsize(resultdef);
+                      location_force_fpureg(current_asmdata.CurrAsmList,left.location,false);
+                      location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
+                      cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,left.location.size,location.size,left.location.register,location.register);
                     end;
                     end;
                   LOC_MMREGISTER:
                   LOC_MMREGISTER:
-                    ;
+                    begin
+                      location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
+                      cg.a_loadmm_reg_reg(current_asmdata.CurrAsmList,left.location.size,location.size,left.location.register,location.register,nil);
+                    end;
                   else
                   else
                     internalerror(2003012261);
                     internalerror(2003012261);
                 end;
                 end;

+ 2 - 16
compiler/x86/cgx86.pas

@@ -915,22 +915,8 @@ unit cgx86;
       var
       var
         instr : taicpu;
         instr : taicpu;
       begin
       begin
-        if shuffle=nil then
-          begin
-            if fromsize=tosize then
-              { needs correct size in case of spilling }
-              case fromsize of
-                OS_F32:
-                  instr:=taicpu.op_reg_reg(A_MOVAPS,S_NO,reg1,reg2);
-                OS_F64:
-                  instr:=taicpu.op_reg_reg(A_MOVAPD,S_NO,reg1,reg2);
-                else
-                  internalerror(2006091201);
-              end
-            else
-              internalerror(200312202);
-          end
-        else if shufflescalar(shuffle) then
+        if (shuffle=nil) or
+           shufflescalar(shuffle) then
           instr:=taicpu.op_reg_reg(get_scalar_mm_op(fromsize,tosize),S_NO,reg1,reg2)
           instr:=taicpu.op_reg_reg(get_scalar_mm_op(fromsize,tosize),S_NO,reg1,reg2)
         else
         else
           internalerror(200312201);
           internalerror(200312201);