Browse Source

* set the subregsize of OS_M64 SSE registers to R_SUBQ so we can
differentiate between 64 bit and 128 bit (R_SUBMMWHOLE) SSE vector regs,
and support spilling/assembling for R_SUBQ SSE registers (8 bytes)
(mantis #23962)

We currently never use the full 128 bit of an SSE register, and
spilling for those hasn't been implemented yet either (R_SUBMMWHOLE
SSE regs are spilled into a 4-byte temp currently -> can overwrite data)

git-svn-id: trunk@23700 -

Jonas Maebe 12 years ago
parent
commit
5d628b29bb
5 changed files with 53 additions and 3 deletions
  1. 1 0
      .gitattributes
  2. 2 0
      compiler/x86/aasmcpu.pas
  3. 2 1
      compiler/x86/cgx86.pas
  4. 2 2
      compiler/x86_64/cpupara.pas
  5. 46 0
      tests/webtbs/tw23962.pp

+ 1 - 0
.gitattributes

@@ -13237,6 +13237,7 @@ tests/webtbs/tw2378.pp svneol=native#text/plain
 tests/webtbs/tw23819.pp -text svneol=native#text/plain
 tests/webtbs/tw2382.pp svneol=native#text/plain
 tests/webtbs/tw2388.pp svneol=native#text/plain
+tests/webtbs/tw23962.pp svneol=native#text/plain
 tests/webtbs/tw2397.pp svneol=native#text/plain
 tests/webtbs/tw2409.pp svneol=native#text/plain
 tests/webtbs/tw2421.pp svneol=native#text/plain

+ 2 - 0
compiler/x86/aasmcpu.pas

@@ -2892,6 +2892,7 @@ implementation
                 result:=taicpu.op_ref_reg(A_MOVSD,reg2opsize(r),ref,r);
               R_SUBMMS:
                 result:=taicpu.op_ref_reg(A_MOVSS,reg2opsize(r),ref,r);
+              R_SUBQ,
               R_SUBMMWHOLE:
                 result:=taicpu.op_ref_reg(A_MOVQ,S_NO,ref,r);
               else
@@ -2928,6 +2929,7 @@ implementation
                 result:=taicpu.op_reg_ref(A_MOVSD,reg2opsize(r),r,ref);
               R_SUBMMS:
                 result:=taicpu.op_reg_ref(A_MOVSS,reg2opsize(r),r,ref);
+              R_SUBQ,
               R_SUBMMWHOLE:
                 result:=taicpu.op_reg_ref(A_MOVQ,S_NO,r,ref);
               else

+ 2 - 1
compiler/x86/cgx86.pas

@@ -206,7 +206,8 @@ unit cgx86;
             result:=rg[R_MMREGISTER].getregister(list,R_SUBMMD);
           OS_F32:
             result:=rg[R_MMREGISTER].getregister(list,R_SUBMMS);
-          OS_M64,
+          OS_M64:
+            result:=rg[R_MMREGISTER].getregister(list,R_SUBQ);
           OS_M128:
             result:=rg[R_MMREGISTER].getregister(list,R_SUBMMWHOLE);
           else

+ 2 - 2
compiler/x86_64/cpupara.pas

@@ -925,7 +925,7 @@ unit cpupara;
                           end;
                         else
                           begin
-                            setsubreg(paraloc^.register,R_SUBMMWHOLE);
+                            setsubreg(paraloc^.register,R_SUBQ);
                             paraloc^.size:=OS_M64;
                           end;
                       end;
@@ -1121,7 +1121,7 @@ unit cpupara;
                               end;
                             else
                               begin
-                                subreg:=R_SUBMMWHOLE;
+                                subreg:=R_SUBQ;
                                 paraloc^.size:=OS_M64;
                               end;
                           end;

+ 46 - 0
tests/webtbs/tw23962.pp

@@ -0,0 +1,46 @@
+{$MODE ObjFpc}
+
+uses classes;
+
+type
+
+TVector3 = packed record
+  X, Y, Z: Single;
+end;
+
+TClassA = class
+protected
+  fVector: TVector3;
+public
+  procedure SetVector(AVector: TVector3); virtual; abstract;
+end;
+
+{ TClassB }
+
+TClassB = class(TClassA)
+public
+  procedure SetVector(AVector: TVector3); override;
+end;
+
+{ TClassB }
+
+procedure TClassB.SetVector(AVector: TVector3);
+begin
+  writeln('TClassB: ',AVector.X,',',AVector.Y,',',AVector.Z);
+  fVector:=AVector;
+end;
+
+var
+  MyVector: TVector3;
+  MyClassB: TClassB;
+begin
+  MyVector.X:=0;
+  MyVector.Y:=0;
+  MyVector.Z:=3;
+  MyClassB:=TClassB.Create;
+  MyClassB.SetVector(MyVector);
+  if (MyClassB.fvector.x<>0) or
+     (MyClassB.fvector.y<>0) or
+     (MyClassB.fvector.z<>3) then
+    halt(1);
+end.