Ver Fonte

* more stuff of r199 merged

git-svn-id: branches/fixes_2_0@3995 -
florian há 19 anos atrás
pai
commit
2233b2491c

+ 7 - 1
compiler/cgbase.pas

@@ -129,7 +129,9 @@ interface
         { For Sparc floats that use F0:F1 to store doubles }
         R_SUBFS,   { = 6; Float that allocates 1 FPU register }
         R_SUBFD,   { = 7; Float that allocates 2 FPU registers }
-        R_SUBFQ    { = 8; Float that allocates 4 FPU registers }
+        R_SUBFQ,   { = 8; Float that allocates 4 FPU registers }
+        R_SUBMMS,  { = 9; single scalar in multi media register }
+        R_SUBMMD   { = 10; double scalar in multi media register }
       );
 
       TSuperRegister = type word;
@@ -501,6 +503,10 @@ implementation
             result:=result+'fs';
           R_SUBFD:
             result:=result+'fd';
+          R_SUBMMD:
+            result:=result+'md';
+          R_SUBMMS:
+            result:=result+'ms';
           else
             internalerror(200308252);
         end;

+ 4 - 0
compiler/cgobj.pas

@@ -1408,7 +1408,9 @@ implementation
         paramanager.freeparaloc(list,cgpara1);
         alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         alloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
+        alloccpuregisters(list,R_MMREGISTER,paramanager.get_volatile_registers_mm(pocall_default));
         a_call_name(list,'FPC_SHORTSTR_ASSIGN');
+        dealloccpuregisters(list,R_MMREGISTER,paramanager.get_volatile_registers_mm(pocall_default));
         dealloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
         dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         cgpara3.done;
@@ -1458,6 +1460,8 @@ implementation
             a_param_ref(list,OS_ADDR,ref,cgpara1);
             paramanager.freeparaloc(list,cgpara1);
             alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+            alloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
+            alloccpuregisters(list,R_MMREGISTER,paramanager.get_volatile_registers_int(pocall_default));
             a_call_name(list,incrfunc);
             dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
           end

+ 14 - 1
compiler/symdef.pas

@@ -848,6 +848,10 @@ interface
     function is_class_or_interface(def: tdef): boolean;
 
 
+{$ifdef x86}
+    function use_sse(def : tdef) : boolean;
+{$endif x86}
+
 implementation
 
     uses
@@ -1336,7 +1340,7 @@ implementation
    function tstoreddef.is_fpuregable : boolean;
      begin
 {$ifdef x86}
-       result:=false;
+       result:=use_sse(self);
 {$else x86}
        result:=(deftype=floatdef);
 {$endif x86}
@@ -6597,4 +6601,13 @@ implementation
           (tobjectdef(def).objecttype in [odt_class,odt_interfacecom,odt_interfacecorba]);
       end;
 
+
+{$ifdef x86}
+    function use_sse(def : tdef) : boolean;
+      begin
+        use_sse:=(is_single(def) and (aktfputype in sse_singlescalar)) or
+          (is_double(def) and (aktfputype in sse_doublescalar));
+      end;
+{$endif x86}
+
 end.

+ 32 - 3
compiler/x86/aasmcpu.pas

@@ -2040,7 +2040,22 @@ implementation
 
     function taicpu.spilling_get_operation_type(opnr: longint): topertype;
       begin
-        result:=operation_type_table^[opcode,opnr];
+        { the information in the instruction table is made for the string copy
+          operation MOVSD so hack here (FK)
+        }
+        if (opcode=A_MOVSD) and (ops=2) then
+          begin
+            case opnr of
+              0:
+                result:=operand_read;
+              1:
+                result:=operand_write;
+              else
+                internalerror(200506055);
+            end
+          end
+        else
+          result:=operation_type_table^[opcode,opnr];
       end;
 
 
@@ -2050,7 +2065,14 @@ implementation
           R_INTREGISTER :
             result:=taicpu.op_ref_reg(A_MOV,reg2opsize(r),ref,r);
           R_MMREGISTER :
-            result:=taicpu.op_ref_reg(A_MOVSD,reg2opsize(r),ref,r);
+            case getsubreg(r) of
+              R_SUBMMD:
+                result:=taicpu.op_ref_reg(A_MOVSD,reg2opsize(r),ref,r);
+              R_SUBMMS:
+                result:=taicpu.op_ref_reg(A_MOVSS,reg2opsize(r),ref,r);
+              else
+                internalerror(200506043);
+            end;
           else
             internalerror(200401041);
         end;
@@ -2063,7 +2085,14 @@ implementation
           R_INTREGISTER :
             result:=taicpu.op_reg_ref(A_MOV,reg2opsize(r),r,ref);
           R_MMREGISTER :
-            result:=taicpu.op_reg_ref(A_MOVSD,reg2opsize(r),r,ref);
+            case getsubreg(r) of
+              R_SUBMMD:
+                result:=taicpu.op_reg_ref(A_MOVSD,reg2opsize(r),r,ref);
+              R_SUBMMS:
+                result:=taicpu.op_reg_ref(A_MOVSS,reg2opsize(r),r,ref);
+              else
+                internalerror(200506042);
+            end;
           else
             internalerror(200401041);
         end;

+ 18 - 9
compiler/x86/cgx86.pas

@@ -41,6 +41,7 @@ unit cgx86;
 
         function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
         function getmmxregister(list:Taasmoutput):Tregister;
+        function getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
 
         procedure getcpuregister(list:Taasmoutput;r:Tregister);override;
         procedure ungetcpuregister(list:Taasmoutput;r:Tregister);override;
@@ -126,8 +127,6 @@ unit cgx86;
         procedure floatstoreops(t : tcgsize;var op : tasmop;var s : topsize);
       end;
 
-    function use_sse(def : tdef) : boolean;
-
    const
 {$ifdef x86_64}
       TCGSize2OpSize: Array[tcgsize] of topsize =
@@ -163,13 +162,6 @@ unit cgx86;
       TOpCmp2AsmCond: Array[topcmp] of TAsmCond = (C_NONE,
           C_E,C_G,C_L,C_GE,C_LE,C_NE,C_BE,C_B,C_AE,C_A);
 
-    function use_sse(def : tdef) : boolean;
-      begin
-        use_sse:=(is_single(def) and (aktfputype in sse_singlescalar)) or
-          (is_double(def) and (aktfputype in sse_doublescalar));
-      end;
-
-
     procedure Tcgx86.done_register_allocators;
       begin
         rg[R_INTREGISTER].free;
@@ -185,6 +177,7 @@ unit cgx86;
         result:=rgfpu.getregisterfpu(list);
       end;
 
+
     function Tcgx86.getmmxregister(list:Taasmoutput):Tregister;
       begin
         if not assigned(rg[R_MMXREGISTER]) then
@@ -192,6 +185,22 @@ unit cgx86;
         result:=rg[R_MMXREGISTER].getregister(list,R_SUBNONE);
       end;
 
+
+    function Tcgx86.getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;
+      begin
+        if not assigned(rg[R_MMXREGISTER]) then
+          internalerror(200312124);
+        case size of
+          OS_F64:
+            result:=rg[R_MMREGISTER].getregister(list,R_SUBMMD);
+          OS_F32:
+            result:=rg[R_MMREGISTER].getregister(list,R_SUBMMS);
+          else
+            internalerror(200506041);
+        end;
+      end;
+
+
     procedure Tcgx86.getcpuregister(list:Taasmoutput;r:Tregister);
       begin
         if getregtype(r)=R_FPUREGISTER then

+ 12 - 4
compiler/x86/cpubase.pas

@@ -314,7 +314,7 @@ implementation
 
     function reg_cgsize(const reg: tregister): tcgsize;
       const subreg2cgsize:array[Tsubregister] of Tcgsize =
-            (OS_NO,OS_8,OS_8,OS_16,OS_32,OS_64,OS_NO,OS_NO,OS_NO);
+            (OS_NO,OS_8,OS_8,OS_16,OS_32,OS_64,OS_NO,OS_NO,OS_NO,OS_F32,OS_F64);
       begin
         case getregtype(reg) of
           R_INTREGISTER :
@@ -324,7 +324,7 @@ implementation
           R_MMXREGISTER:
             reg_cgsize:=OS_M64;
           R_MMREGISTER:
-            reg_cgsize:=OS_M128;
+            reg_cgsize:=subreg2cgsize[getsubreg(reg)];
           R_SPECIALREGISTER :
             case reg of
               NR_CS,NR_DS,NR_ES,NR_SS,NR_FS,NR_GS:
@@ -341,7 +341,7 @@ implementation
     function reg2opsize(r:Tregister):topsize;
       const
         subreg2opsize : array[tsubregister] of topsize =
-          (S_NO,S_B,S_B,S_W,S_L,S_Q,S_NO,S_NO,S_NO);
+          (S_NO,S_B,S_B,S_W,S_L,S_Q,S_NO,S_NO,S_NO,S_NO,S_NO);
       begin
         reg2opsize:=S_L;
         case getregtype(r) of
@@ -418,8 +418,16 @@ implementation
 
 
     function findreg_by_number(r:Tregister):tregisterindex;
+      var
+        hr : tregister;
       begin
-        result:=findreg_by_number_table(r,regnumber_index);
+        { for the name the sub reg doesn't matter }
+        hr:=r;
+        case getsubreg(hr) of
+          R_SUBMMS,R_SUBMMD:
+            setsubreg(hr,R_SUBNONE);
+        end;
+        result:=findreg_by_number_table(hr,regnumber_index);
       end;
 
 

+ 1 - 1
compiler/x86/nx86add.pas

@@ -65,7 +65,7 @@ unit nx86add;
       verbose,cutils,
       cpuinfo,
       aasmbase,aasmtai,aasmcpu,
-      symconst,
+      symconst,symdef,
       cgobj,cgx86,cga,cgutils,
       paramgr,tgobj,ncgutil,
       ncon,nset,

+ 1 - 1
compiler/x86/nx86mat.pas

@@ -50,7 +50,7 @@ interface
       globtype,
       systems,
       cutils,verbose,globals,
-      symconst,aasmbase,aasmtai,defutil,
+      symconst,symdef,aasmbase,aasmtai,defutil,
       cgbase,pass_1,pass_2,
       ncon,
       cpubase,