소스 검색

* x86_64: More support for transferring directly between MM and int registers

J. Gareth "Curious Kit" Moreton 3 달 전
부모
커밋
927020d981
2개의 변경된 파일37개의 추가작업 그리고 0개의 파일을 삭제
  1. 18 0
      compiler/ncgcnv.pas
  2. 19 0
      compiler/x86_64/nx64cnv.pas

+ 18 - 0
compiler/ncgcnv.pas

@@ -826,7 +826,25 @@ interface
               end
             else
 {$endif cpufloatintregmov}
+{$ifdef cpumm}
+            if (resultdef.typ<>floatdef) and (location.loc in [LOC_CMMREGISTER,LOC_MMREGISTER]) then
+              begin
+                location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
+                location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
+                cg.a_loadmm_reg_intreg(current_asmdata.CurrAsmList,left.location.size,location.size,left.location.register,location.register, nil);
+              end
+            else
+{$endif cpumm}
               hlcg.location_force_mem(current_asmdata.CurrAsmList,location,left.resultdef);
+{$ifdef cpumm}
+          end
+        else if (resultdef.typ=floatdef) and (location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+          begin
+            { Take advantage of direct moves from int to MM if supported }
+            location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef));
+            location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
+            cg.a_loadmm_intreg_reg(current_asmdata.CurrAsmList,left.location.size,location.size,left.location.register,location.register, nil);
+{$endif cpumm}
           end;
         { but use the new size, but we don't know the size of all arrays }
         newsize:=def_cgsize(resultdef);

+ 19 - 0
compiler/x86_64/nx64cnv.pas

@@ -32,6 +32,7 @@ interface
     type
        tx8664typeconvnode = class(tx86typeconvnode)
          protected
+         function first_nothing : tnode;override;
          { procedure second_int_to_int;override; }
          { procedure second_string_to_string;override; }
          { procedure second_cstring_to_pchar;override; }
@@ -68,6 +69,24 @@ implementation
       cgutils,cgobj,hlcgobj,cgx86;
 
 
+    function tx8664typeconvnode.first_nothing : tnode;
+      begin
+        result:=nil;
+        { If typecasting between a Single or Double and a record of equal size,
+          we can use MOVD and MOVQ }
+        if (resultdef.typ in [recorddef,orddef]) and
+          use_vectorfpu(left.resultdef) and
+          (resultdef.size=left.resultdef.size) then
+          expectloc:=LOC_MMREGISTER
+        else if (left.resultdef.typ in [recorddef,orddef]) and
+          use_vectorfpu(resultdef) and
+          (resultdef.size=left.resultdef.size) then
+          expectloc:=LOC_REGISTER
+        else
+          result:=inherited first_nothing;
+      end;
+
+
     function tx8664typeconvnode.first_int_to_real : tnode;
       begin
         result:=nil;