Browse Source

+ mmx support revived, fixes bug #4106

git-svn-id: trunk@555 -
florian 20 years ago
parent
commit
dac1050c11

+ 1 - 0
compiler/fpcdefs.inc

@@ -36,6 +36,7 @@
   {$define cpuflags}
   {$define cpuextended}
   {$define USECMOV}
+  {$define SUPPORT_MMX}
 {$endif i386}
 
 {$ifdef x86_64}

+ 3 - 270
compiler/i386/n386add.pas

@@ -30,13 +30,9 @@ interface
 
     type
        ti386addnode = class(tx86addnode)
-{$ifdef SUPPORT_MMX}
-          procedure second_addmmxset;override;
-          procedure second_addmmx;override;
-{$endif SUPPORT_MMX}
-          procedure second_add64bit;override;
-          procedure second_cmp64bit;override;
-          procedure second_mul;override;
+         procedure second_add64bit;override;
+         procedure second_cmp64bit;override;
+         procedure second_mul;override;
        end;
 
   implementation
@@ -50,86 +46,6 @@ interface
       ncon,nset,cgutils,tgobj,
       cga,ncgutil,cgobj,cg64f32;
 
-{*****************************************************************************
-                                   addmmxset
-*****************************************************************************}
-
-{$ifdef SUPPORT_MMX}
-    procedure ti386addnode.second_addmmxset;
-
-    var opsize : TCGSize;
-        op     : TAsmOp;
-        cmpop,
-        pushedfpu,
-        noswap : boolean;
-    begin
-      pass_left_and_right(pushedfpu);
-
-      cmpop:=false;
-      noswap:=false;
-      opsize:=OS_32;
-      case nodetype of
-        addn:
-          begin
-            { are we adding set elements ? }
-            if right.nodetype=setelementn then
-              begin
-                { adding elements is not commutative }
-{                if nf_swaped in flags then
-                  swapleftright;}
-                { bts requires both elements to be registers }
-{                location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],false);
-                location_force_reg(exprasmlist,right.location,opsize_2_cgsize[opsize],true);
-                op:=A_BTS;
-                noswap:=true;}
-              end
-            else
-              op:=A_POR;
-          end;
-        symdifn :
-          op:=A_PXOR;
-        muln:
-          op:=A_PAND;
-        subn:
-          op:=A_PANDN;
-        equaln,
-        unequaln :
-          begin
-            op:=A_PCMPEQD;
-            cmpop:=true;
-          end;
-        lten,gten:
-          begin
-            if (not(nf_swaped in flags) and (nodetype = lten)) or
-               ((nf_swaped in flags) and (nodetype = gten)) then
-              swapleftright;
-            location_force_reg(exprasmlist,left.location,opsize,true);
-            emit_op_right_left(A_AND,TCGSize2Opsize[opsize]);
-            op:=A_PCMPEQD;
-            cmpop:=true;
-            { warning: ugly hack, we need a JE so change the node to equaln }
-            nodetype:=equaln;
-          end;
-          xorn :
-            op:=A_PXOR;
-          orn :
-            op:=A_POR;
-          andn :
-            op:=A_PAND;
-          else
-            internalerror(2003042215);
-        end;
-        { left must be a register }
-        left_must_be_reg(opsize,noswap);
-{        emit_generic_code(op,opsize,true,extra_not,false);}
-        location_freetemp(exprasmlist,right.location);
-        if cmpop then
-          location_freetemp(exprasmlist,left.location);
-        set_result_location(cmpop,true);
-      end;
-{$endif SUPPORT_MMX}
-
-
 {*****************************************************************************
                                 Add64bit
 *****************************************************************************}
@@ -423,189 +339,6 @@ interface
       end;
 
 
-{*****************************************************************************
-                                AddMMX
-*****************************************************************************}
-
-{$ifdef SUPPORT_MMX}
-    procedure ti386addnode.second_addmmx;
-      var
-        op         : TAsmOp;
-        pushedfpu,
-        cmpop      : boolean;
-        mmxbase    : tmmxtype;
-        hreg,
-        hregister  : tregister;
-      begin
-        pass_left_and_right(pushedfpu);
-
-        cmpop:=false;
-        mmxbase:=mmx_type(left.resulttype.def);
-        case nodetype of
-          addn :
-            begin
-              if (cs_mmx_saturation in aktlocalswitches) then
-                begin
-                   case mmxbase of
-                      mmxs8bit:
-                        op:=A_PADDSB;
-                      mmxu8bit:
-                        op:=A_PADDUSB;
-                      mmxs16bit,mmxfixed16:
-                        op:=A_PADDSB;
-                      mmxu16bit:
-                        op:=A_PADDUSW;
-                   end;
-                end
-              else
-                begin
-                   case mmxbase of
-                      mmxs8bit,mmxu8bit:
-                        op:=A_PADDB;
-                      mmxs16bit,mmxu16bit,mmxfixed16:
-                        op:=A_PADDW;
-                      mmxs32bit,mmxu32bit:
-                        op:=A_PADDD;
-                   end;
-                end;
-            end;
-          muln :
-            begin
-               case mmxbase of
-                  mmxs16bit,mmxu16bit:
-                    op:=A_PMULLW;
-                  mmxfixed16:
-                    op:=A_PMULHW;
-               end;
-            end;
-          subn :
-            begin
-              if (cs_mmx_saturation in aktlocalswitches) then
-                begin
-                   case mmxbase of
-                      mmxs8bit:
-                        op:=A_PSUBSB;
-                      mmxu8bit:
-                        op:=A_PSUBUSB;
-                      mmxs16bit,mmxfixed16:
-                        op:=A_PSUBSB;
-                      mmxu16bit:
-                        op:=A_PSUBUSW;
-                   end;
-                end
-              else
-                begin
-                   case mmxbase of
-                      mmxs8bit,mmxu8bit:
-                        op:=A_PSUBB;
-                      mmxs16bit,mmxu16bit,mmxfixed16:
-                        op:=A_PSUBW;
-                      mmxs32bit,mmxu32bit:
-                        op:=A_PSUBD;
-                   end;
-                end;
-            end;
-          xorn:
-            op:=A_PXOR;
-          orn:
-            op:=A_POR;
-          andn:
-            op:=A_PAND;
-          else
-            internalerror(2003042214);
-        end;
-
-        { left and right no register?  }
-        { then one must be demanded    }
-        if (left.location.loc<>LOC_MMXREGISTER) then
-         begin
-           if (right.location.loc=LOC_MMXREGISTER) then
-            begin
-              location_swap(left.location,right.location);
-              toggleflag(nf_swaped);
-            end
-           else
-            begin
-              { register variable ? }
-              if (left.location.loc=LOC_CMMXREGISTER) then
-               begin
-                 hregister:=cg.getmmxregister(exprasmlist,OS_M64);
-                 emit_reg_reg(A_MOVQ,S_NO,left.location.register,hregister);
-               end
-              else
-               begin
-                 if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
-                  internalerror(200203245);
-
-                 hregister:=cg.getmmxregister(exprasmlist,OS_M64);
-                 emit_ref_reg(A_MOVQ,S_NO,left.location.reference,hregister);
-               end;
-
-              location_reset(left.location,LOC_MMXREGISTER,OS_NO);
-              left.location.register:=hregister;
-            end;
-         end;
-
-        { at this point, left.location.loc should be LOC_MMXREGISTER }
-        if right.location.loc<>LOC_MMXREGISTER then
-         begin
-           if (nodetype=subn) and (nf_swaped in flags) then
-            begin
-              if right.location.loc=LOC_CMMXREGISTER then
-               begin
-                 hreg:=cg.getmmxregister(exprasmlist,OS_M64);
-                 emit_reg_reg(A_MOVQ,S_NO,right.location.register,hreg);
-                 emit_reg_reg(op,S_NO,left.location.register,hreg);
-                 cg.ungetregister(exprasmlist,hreg);
-                 emit_reg_reg(A_MOVQ,S_NO,hreg,left.location.register);
-               end
-              else
-               begin
-                 if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
-                  internalerror(200203247);
-                 hreg:=cg.getmmxregister(exprasmlist,OS_M64);
-                 emit_ref_reg(A_MOVQ,S_NO,right.location.reference,hreg);
-                 emit_reg_reg(op,S_NO,left.location.register,hreg);
-                 cg.ungetregister(exprasmlist,hreg);
-                 emit_reg_reg(A_MOVQ,S_NO,hreg,left.location.register);
-               end;
-            end
-           else
-            begin
-              if (right.location.loc=LOC_CMMXREGISTER) then
-                emit_reg_reg(op,S_NO,right.location.register,left.location.register)
-              else
-               begin
-                 if not(right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
-                  internalerror(200203246);
-                 emit_ref_reg(op,S_NO,right.location.reference,left.location.register);
-               end;
-            end;
-          end
-        else
-          begin
-            { right.location=LOC_MMXREGISTER }
-            if (nodetype=subn) and (nf_swaped in flags) then
-             begin
-               emit_reg_reg(op,S_NO,left.location.register,right.location.register);
-               location_swap(left.location,right.location);
-               toggleflag(nf_swaped);
-             end
-            else
-             begin
-               emit_reg_reg(op,S_NO,right.location.register,left.location.register);
-             end;
-          end;
-
-        location_freetemp(exprasmlist,right.location);
-        if cmpop then
-          location_freetemp(exprasmlist,left.location);
-
-        set_result_location(cmpop,true);
-      end;
-{$endif SUPPORT_MMX}
-
-
 {*****************************************************************************
                                 x86 MUL
 *****************************************************************************}

+ 5 - 5
compiler/ncgadd.pas

@@ -50,12 +50,12 @@ interface
           procedure second_addfloat;virtual;abstract;
           procedure second_addboolean;virtual;
           procedure second_addsmallset;virtual;
-{$ifdef i386}
+{$ifdef x86}
 {$ifdef SUPPORT_MMX}
-          procedure second_addmmxset;virtual;abstract;
-          procedure second_addmmx;virtual;abstract;
+          procedure second_opmmxset;virtual;abstract;
+          procedure second_opmmx;virtual;abstract;
 {$endif SUPPORT_MMX}
-{$endif}
+{$endif x86}
           procedure second_add64bit;virtual;
           procedure second_addordinal;virtual;
           procedure second_cmpfloat;virtual;abstract;
@@ -775,7 +775,7 @@ interface
 {$ifdef SUPPORT_MMX}
               else
                 if is_mmx_able_array(left.resulttype.def) then
-                  second_opmmx;
+                  second_opmmx
 {$endif SUPPORT_MMX}
               else
                 internalerror(200306016);

+ 1 - 1
compiler/ncgcal.pas

@@ -301,7 +301,7 @@ implementation
 {$ifdef SUPPORT_MMX}
              LOC_MMXREGISTER,
              LOC_CMMXREGISTER:
-               cg.a_parammm_reg(exprasmlist,left.location.register);
+               cg.a_parammm_reg(exprasmlist,OS_M64,left.location.register,tempcgpara,nil);
 {$endif SUPPORT_MMX}
              else
                internalerror(200204241);

+ 2 - 2
compiler/ncgld.pas

@@ -607,9 +607,9 @@ implementation
               LOC_MMXREGISTER:
                 begin
                   if left.location.loc=LOC_CMMXREGISTER then
-                    cg.a_loadmm_reg_reg(exprasmlist,right.location.register,left.location.register)
+                    cg.a_loadmm_reg_reg(exprasmlist,OS_M64,OS_M64,right.location.register,left.location.register,nil)
                   else
-                    cg.a_loadmm_reg_ref(exprasmlist,right.location.register,left.location.reference);
+                    cg.a_loadmm_reg_ref(exprasmlist,OS_M64,OS_M64,right.location.register,left.location.reference,nil);
                 end;
 {$endif SUPPORT_MMX}
               LOC_MMREGISTER,

+ 1 - 1
compiler/node.pas

@@ -839,7 +839,7 @@ implementation
          p.registersfpu:=registersfpu;
 {$ifdef SUPPORT_MMX}
          p.registersmmx:=registersmmx;
-         p.registerskni:=registerskni;
+         p.registersmm:=registersmm;
 {$endif SUPPORT_MMX}
          p.resulttype:=resulttype;
          p.fileinfo:=fileinfo;

+ 262 - 0
compiler/x86/nx86add.pas

@@ -51,6 +51,10 @@ unit nx86add;
         procedure second_cmpsmallset;override;
         procedure second_cmp64bit;override;
         procedure second_cmpordinal;override;
+{$ifdef SUPPORT_MMX}
+        procedure second_opmmxset;override;
+        procedure second_opmmx;override;
+{$endif SUPPORT_MMX}
       end;
 
 
@@ -434,6 +438,264 @@ unit nx86add;
       end;
 
 
+{*****************************************************************************
+                                AddMMX
+*****************************************************************************}
+
+{$ifdef SUPPORT_MMX}
+    procedure tx86addnode.second_opmmx;
+      var
+        op         : TAsmOp;
+        cmpop      : boolean;
+        mmxbase    : tmmxtype;
+        hreg,
+        hregister  : tregister;
+      begin
+        pass_left_right;
+
+        cmpop:=false;
+        mmxbase:=mmx_type(left.resulttype.def);
+        location_reset(location,LOC_MMXREGISTER,def_cgsize(resulttype.def));
+        case nodetype of
+          addn :
+            begin
+              if (cs_mmx_saturation in aktlocalswitches) then
+                begin
+                   case mmxbase of
+                      mmxs8bit:
+                        op:=A_PADDSB;
+                      mmxu8bit:
+                        op:=A_PADDUSB;
+                      mmxs16bit,mmxfixed16:
+                        op:=A_PADDSB;
+                      mmxu16bit:
+                        op:=A_PADDUSW;
+                   end;
+                end
+              else
+                begin
+                   case mmxbase of
+                      mmxs8bit,mmxu8bit:
+                        op:=A_PADDB;
+                      mmxs16bit,mmxu16bit,mmxfixed16:
+                        op:=A_PADDW;
+                      mmxs32bit,mmxu32bit:
+                        op:=A_PADDD;
+                   end;
+                end;
+            end;
+          muln :
+            begin
+               case mmxbase of
+                  mmxs16bit,mmxu16bit:
+                    op:=A_PMULLW;
+                  mmxfixed16:
+                    op:=A_PMULHW;
+               end;
+            end;
+          subn :
+            begin
+              if (cs_mmx_saturation in aktlocalswitches) then
+                begin
+                   case mmxbase of
+                      mmxs8bit:
+                        op:=A_PSUBSB;
+                      mmxu8bit:
+                        op:=A_PSUBUSB;
+                      mmxs16bit,mmxfixed16:
+                        op:=A_PSUBSB;
+                      mmxu16bit:
+                        op:=A_PSUBUSW;
+                   end;
+                end
+              else
+                begin
+                   case mmxbase of
+                      mmxs8bit,mmxu8bit:
+                        op:=A_PSUBB;
+                      mmxs16bit,mmxu16bit,mmxfixed16:
+                        op:=A_PSUBW;
+                      mmxs32bit,mmxu32bit:
+                        op:=A_PSUBD;
+                   end;
+                end;
+            end;
+          xorn:
+            op:=A_PXOR;
+          orn:
+            op:=A_POR;
+          andn:
+            op:=A_PAND;
+          else
+            internalerror(2003042214);
+        end;
+
+        { left and right no register?  }
+        { then one must be demanded    }
+        if (left.location.loc<>LOC_MMXREGISTER) then
+         begin
+           if (right.location.loc=LOC_MMXREGISTER) then
+            begin
+              location_swap(left.location,right.location);
+              toggleflag(nf_swaped);
+            end
+           else
+            begin
+              { register variable ? }
+              if (left.location.loc=LOC_CMMXREGISTER) then
+               begin
+                 hregister:=tcgx86(cg).getmmxregister(exprasmlist);
+                 emit_reg_reg(A_MOVQ,S_NO,left.location.register,hregister);
+               end
+              else
+               begin
+                 if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+                  internalerror(200203245);
+
+                 hregister:=tcgx86(cg).getmmxregister(exprasmlist);
+                 emit_ref_reg(A_MOVQ,S_NO,left.location.reference,hregister);
+               end;
+
+              location_reset(left.location,LOC_MMXREGISTER,OS_NO);
+              left.location.register:=hregister;
+            end;
+         end;
+
+        { at this point, left.location.loc should be LOC_MMXREGISTER }
+        if right.location.loc<>LOC_MMXREGISTER then
+         begin
+           if (nodetype=subn) and (nf_swaped in flags) then
+            begin
+              hreg:=tcgx86(cg).getmmxregister(exprasmlist);
+              if right.location.loc=LOC_CMMXREGISTER then
+               begin
+                 emit_reg_reg(A_MOVQ,S_NO,right.location.register,hreg);
+                 emit_reg_reg(op,S_NO,left.location.register,hreg);
+               end
+              else
+               begin
+                 if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+                  internalerror(200203247);
+                 emit_ref_reg(A_MOVQ,S_NO,right.location.reference,hreg);
+                 emit_reg_reg(op,S_NO,left.location.register,hreg);
+               end;
+               location.register:=hreg;
+            end
+           else
+            begin
+              if (right.location.loc=LOC_CMMXREGISTER) then
+                emit_reg_reg(op,S_NO,right.location.register,left.location.register)
+              else
+               begin
+                 if not(right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+                  internalerror(200203246);
+                 emit_ref_reg(op,S_NO,right.location.reference,left.location.register);
+               end;
+              location.register:=left.location.register;
+            end;
+          end
+        else
+          begin
+            { right.location=LOC_MMXREGISTER }
+            if (nodetype=subn) and (nf_swaped in flags) then
+             begin
+               emit_reg_reg(op,S_NO,left.location.register,right.location.register);
+               location_swap(left.location,right.location);
+               toggleflag(nf_swaped);
+             end
+            else
+             begin
+               emit_reg_reg(op,S_NO,right.location.register,left.location.register);
+             end;
+            location.register:=left.location.register;
+          end;
+
+        location_freetemp(exprasmlist,right.location);
+        if cmpop then
+          location_freetemp(exprasmlist,left.location);
+      end;
+{$endif SUPPORT_MMX}
+
+
+{*****************************************************************************
+                                   addmmxset
+*****************************************************************************}
+
+{$ifdef SUPPORT_MMX}
+    procedure tx86addnode.second_opmmxset;
+
+    var opsize : TCGSize;
+        op     : TAsmOp;
+        cmpop,
+        noswap : boolean;
+    begin
+      pass_left_right;
+
+      cmpop:=false;
+      noswap:=false;
+      opsize:=OS_32;
+      case nodetype of
+        addn:
+          begin
+            { are we adding set elements ? }
+            if right.nodetype=setelementn then
+              begin
+                { adding elements is not commutative }
+{                if nf_swaped in flags then
+                  swapleftright;}
+                { bts requires both elements to be registers }
+{                location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],false);
+                location_force_reg(exprasmlist,right.location,opsize_2_cgsize[opsize],true);
+                op:=A_BTS;
+                noswap:=true;}
+              end
+            else
+              op:=A_POR;
+          end;
+        symdifn :
+          op:=A_PXOR;
+        muln:
+          op:=A_PAND;
+        subn:
+          op:=A_PANDN;
+        equaln,
+        unequaln :
+          begin
+            op:=A_PCMPEQD;
+            cmpop:=true;
+          end;
+        lten,gten:
+          begin
+            if (not(nf_swaped in flags) and (nodetype = lten)) or
+               ((nf_swaped in flags) and (nodetype = gten)) then
+              swapleftright;
+            location_force_reg(exprasmlist,left.location,opsize,true);
+            emit_op_right_left(A_AND,opsize);
+            op:=A_PCMPEQD;
+            cmpop:=true;
+            { warning: ugly hack, we need a JE so change the node to equaln }
+            nodetype:=equaln;
+          end;
+          xorn :
+            op:=A_PXOR;
+          orn :
+            op:=A_POR;
+          andn :
+            op:=A_PAND;
+          else
+            internalerror(2003042215);
+        end;
+        { left must be a register }
+        left_must_be_reg(opsize,noswap);
+{        emit_generic_code(op,opsize,true,extra_not,false);}
+        location_freetemp(exprasmlist,right.location);
+        if cmpop then
+          location_freetemp(exprasmlist,left.location);
+      end;
+{$endif SUPPORT_MMX}
+
+
+
 {*****************************************************************************
                                 AddFloat
 *****************************************************************************}

+ 9 - 13
compiler/x86/nx86mat.pas

@@ -47,6 +47,7 @@ interface
   implementation
 
     uses
+      globtype,
       systems,
       cutils,verbose,globals,
       symconst,symdef,
@@ -109,7 +110,7 @@ interface
       begin
         secondpass(left);
         location_reset(location,LOC_MMXREGISTER,OS_NO);
-        hreg:=cg.getmmxregister(exprasmlist,OS_M64);
+        hreg:=tcgx86(cg).getmmxregister(exprasmlist);
         emit_reg_reg(A_PXOR,S_NO,hreg,hreg);
         case left.location.loc of
           LOC_MMXREGISTER:
@@ -118,14 +119,13 @@ interface
             end;
           LOC_CMMXREGISTER:
             begin
-               location.register:=cg.getmmxregister(exprasmlist,OS_M64);
+               location.register:=tcgx86(cg).getmmxregister(exprasmlist);
                emit_reg_reg(A_MOVQ,S_NO,left.location.register,location.register);
             end;
           LOC_REFERENCE,
           LOC_CREFERENCE:
             begin
-               reference_release(exprasmlist,left.location.reference);
-               location.register:=cg.getmmxregister(exprasmlist,OS_M64);
+               location.register:=tcgx86(cg).getmmxregister(exprasmlist);
                emit_ref_reg(A_MOVQ,S_NO,left.location.reference,location.register);
             end;
           else
@@ -152,7 +152,6 @@ interface
                op:=A_PSUBD;
           end;
         emit_reg_reg(op,S_NO,location.register,hreg);
-        cg.ungetregister(exprasmlist,hreg);
         emit_reg_reg(A_MOVQ,S_NO,hreg,location.register);
       end;
 {$endif SUPPORT_MMX}
@@ -294,28 +293,25 @@ interface
           location_copy(location,left.location);
         LOC_CMMXREGISTER:
           begin
-            location.register:=cg.getmmxregister(exprasmlist,OS_M64);
+            location.register:=tcgx86(cg).getmmxregister(exprasmlist);
             emit_reg_reg(A_MOVQ,S_NO,left.location.register,location.register);
           end;
         LOC_REFERENCE,
         LOC_CREFERENCE:
           begin
-            location_release(exprasmlist,left.location);
-            location.register:=cg.getmmxregister(exprasmlist,OS_M64);
+            location.register:=tcgx86(cg).getmmxregister(exprasmlist);
             emit_ref_reg(A_MOVQ,S_NO,left.location.reference,location.register);
           end;
       end;
       { load mask }
-      hreg:=cg.getmmxregister(exprasmlist,OS_M64);
+      hreg:=tcgx86(cg).getmmxregister(exprasmlist);
       emit_reg_reg(A_MOVD,S_NO,r,hreg);
-      cg.ungetregister(exprasmlist,r);
       { lower 32 bit }
-      emit_reg_reg(A_PXOR,S_D,hreg,location.register);
+      emit_reg_reg(A_PXOR,S_NO,hreg,location.register);
       { shift mask }
       emit_const_reg(A_PSLLQ,S_NO,32,hreg);
       { higher 32 bit }
-      cg.ungetregister(exprasmlist,hreg);
-      emit_reg_reg(A_PXOR,S_D,hreg,location.register);
+      emit_reg_reg(A_PXOR,S_NO,hreg,location.register);
     end;
 {$endif SUPPORT_MMX}
 end.

+ 0 - 1
tests/test/tmmx1.pp

@@ -1,5 +1,4 @@
 { %CPU=i386 }
-{ %maxversion=1.0.99 }
 
 { this contains currently only a basic test of mmx support }
 { the following instructions are tested: