Răsfoiți Sursa

Merged revisions 8954,8969-8970 via svnmerge from
http://svn.freepascal.org/svn/fpc/trunk

........
r8954 | florian | 2007-10-27 14:02:28 +0200 (Sat, 27 Oct 2007) | 2 lines

+ default code now preserves mm registers
* save|restore_standard_registers => save|restore_registers
........
r8969 | florian | 2007-10-28 15:08:57 +0100 (Sun, 28 Oct 2007) | 2 lines

* store/load mmx registers properly
* sse registers can be stored/loaded aligned on x86-64
........
r8970 | florian | 2007-10-28 15:09:38 +0100 (Sun, 28 Oct 2007) | 1 line

* align locations where mm registers are stored to be preserved
........

git-svn-id: branches/fixes_2_2@10292 -

florian 17 ani în urmă
părinte
comite
591000252b
2 a modificat fișierele cu 38 adăugiri și 12 ștergeri
  1. 16 10
      compiler/cgobj.pas
  2. 22 2
      compiler/x86/cgx86.pas

+ 16 - 10
compiler/cgobj.pas

@@ -471,6 +471,7 @@ unit cgobj;
              @param(usedinproc Registers which are used in the code of this routine)
           }
           procedure g_restore_registers(list:TAsmList);virtual;
+                    
           procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);virtual;abstract;
           procedure g_adjust_self_value(list:TAsmList;procdef: tprocdef;ioffset: aint);virtual;
 
@@ -3608,7 +3609,7 @@ implementation
         size : longint;
         r : integer;
       begin
-        { Get temp }
+        { calculate temp. size }
         size:=0;
         for r:=low(saved_standard_registers) to high(saved_standard_registers) do
           if saved_standard_registers[r] in rg[R_INTREGISTER].used_in_proc then
@@ -3645,15 +3646,20 @@ implementation
               end;
 
             if uses_registers(R_MMREGISTER) then
-              for r:=low(saved_mm_registers) to high(saved_mm_registers) do
-                begin
-                  if saved_mm_registers[r] in rg[R_MMREGISTER].used_in_proc then
-                    begin
-                      a_loadmm_reg_ref(list,OS_VECTOR,OS_VECTOR,newreg(R_MMREGISTER,saved_mm_registers[r],R_SUBNONE),href,nil);
-                      inc(href.offset,tcgsize2size[OS_VECTOR]);
-                    end;
-                  include(rg[R_MMREGISTER].preserved_by_proc,saved_mm_registers[r]);
-                end;
+              begin
+                if (href.offset mod tcgsize2size[OS_VECTOR])<>0 then
+                  inc(href.offset,tcgsize2size[OS_VECTOR]-(href.offset mod tcgsize2size[OS_VECTOR]));
+
+                for r:=low(saved_mm_registers) to high(saved_mm_registers) do
+                  begin
+                    if saved_mm_registers[r] in rg[R_MMREGISTER].used_in_proc then
+                      begin
+                        a_loadmm_reg_ref(list,OS_VECTOR,OS_VECTOR,newreg(R_MMREGISTER,saved_mm_registers[r],R_SUBNONE),href,nil);
+                        inc(href.offset,tcgsize2size[OS_VECTOR]);
+                      end;
+                    include(rg[R_MMREGISTER].preserved_by_proc,saved_mm_registers[r]);
+                  end;
+              end;
           end;
       end;
 

+ 22 - 2
compiler/x86/cgx86.pas

@@ -1016,7 +1016,17 @@ unit cgx86;
          tmpref:=ref;
          make_simple_ref(list,tmpref);
          if shuffle=nil then
-           list.concat(taicpu.op_ref_reg(A_MOVQ,S_NO,tmpref,reg))
+           begin
+             if fromsize=OS_M64 then
+               list.concat(taicpu.op_ref_reg(A_MOVQ,S_NO,tmpref,reg))
+             else
+{$ifdef x86_64}
+               { x86-64 has always properly aligned data }
+               list.concat(taicpu.op_ref_reg(A_MOVDQA,S_NO,tmpref,reg));
+{$else x86_64}
+               list.concat(taicpu.op_ref_reg(A_MOVDQU,S_NO,tmpref,reg));
+{$endif x86_64}
+           end
          else if shufflescalar(shuffle) then
            list.concat(taicpu.op_ref_reg(get_scalar_mm_op(fromsize,tosize),S_NO,tmpref,reg))
          else
@@ -1032,7 +1042,17 @@ unit cgx86;
          tmpref:=ref;
          make_simple_ref(list,tmpref);
          if shuffle=nil then
-           list.concat(taicpu.op_reg_ref(A_MOVQ,S_NO,reg,tmpref))
+           begin
+             if fromsize=OS_M64 then
+               list.concat(taicpu.op_reg_ref(A_MOVQ,S_NO,reg,tmpref))
+             else
+{$ifdef x86_64}
+               { x86-64 has always properly aligned data }
+               list.concat(taicpu.op_reg_ref(A_MOVDQA,S_NO,reg,tmpref))
+{$else x86_64}
+               list.concat(taicpu.op_reg_ref(A_MOVDQU,S_NO,reg,tmpref))
+{$endif x86_64}
+           end
          else if shufflescalar(shuffle) then
            begin
              if tosize<>fromsize then