Browse Source

* make fpu/mmx/xmm/ymm registers numbers instead of flags to have enough space for zmm/bnd/k registers

git-svn-id: trunk@38116 -
florian 7 years ago
parent
commit
e6a6938787
1 changed files with 91 additions and 86 deletions
  1. 91 86
      compiler/x86/aasmcpu.pas

+ 91 - 86
compiler/x86/aasmcpu.pas

@@ -86,6 +86,8 @@ interface
       otf_reg_mmx  = $02000000;
       otf_reg_mmx  = $02000000;
       otf_reg_xmm  = $04000000;
       otf_reg_xmm  = $04000000;
       otf_reg_ymm  = $08000000;
       otf_reg_ymm  = $08000000;
+
+      otf_reg_extra_mask = $0F000000;
       { Bits 16..19: subclasses, meaning depends on classes field }
       { Bits 16..19: subclasses, meaning depends on classes field }
       otf_sub0     = $00010000;
       otf_sub0     = $00010000;
       otf_sub1     = $00020000;
       otf_sub1     = $00020000;
@@ -93,7 +95,9 @@ interface
       otf_sub3     = $00080000;
       otf_sub3     = $00080000;
       OT_REG_SMASK = otf_sub0 or otf_sub1 or otf_sub2 or otf_sub3;
       OT_REG_SMASK = otf_sub0 or otf_sub1 or otf_sub2 or otf_sub3;
 
 
-      OT_REG_TYPMASK = otf_reg_cdt or otf_reg_gpr or otf_reg_sreg or otf_reg_fpu or otf_reg_mmx or otf_reg_xmm or otf_reg_ymm;
+      OT_REG_EXTRA_MASK = $0F000000;
+
+      OT_REG_TYPMASK = otf_reg_cdt or otf_reg_gpr or otf_reg_sreg or otf_reg_extra_mask;
       { register class 0: CRx, DRx and TRx }
       { register class 0: CRx, DRx and TRx }
 {$ifdef x86_64}
 {$ifdef x86_64}
       OT_REG_CDT   = OT_REGISTER or otf_reg_cdt or OT_BITS64;
       OT_REG_CDT   = OT_REGISTER or otf_reg_cdt or OT_BITS64;
@@ -175,7 +179,7 @@ interface
                                              { simple [address] offset  }
                                              { simple [address] offset  }
 
 
       { Matches any type of r/m operand }
       { Matches any type of r/m operand }
-      OT_MEMORY_ANY = OT_MEMORY or OT_RM_GPR or OT_XMMRM or OT_MMXRM or OT_YMMRM;
+      OT_MEMORY_ANY = OT_MEMORY or OT_RM_GPR or OT_XMMRM or OT_MMXRM or OT_YMMRM or OT_REG_EXTRA_MASK;
 
 
       { Immediate operands }
       { Immediate operands }
       OT_IMM8      = OT_IMMEDIATE or OT_BITS8;
       OT_IMM8      = OT_IMMEDIATE or OT_BITS8;
@@ -1096,16 +1100,16 @@ implementation
                 s:=s+',';
                 s:=s+',';
                { type }
                { type }
                addsize:=false;
                addsize:=false;
-               if (ot and OT_XMMREG)=OT_XMMREG then
+               if (ot and OT_REG_EXTRA_MASK)=OT_XMMREG then
                 s:=s+'xmmreg'
                 s:=s+'xmmreg'
                else
                else
-                 if (ot and OT_YMMREG)=OT_YMMREG then
+                 if (ot and OT_REG_EXTRA_MASK)=OT_YMMREG then
                   s:=s+'ymmreg'
                   s:=s+'ymmreg'
                else
                else
-                 if (ot and OT_MMXREG)=OT_MMXREG then
+                 if (ot and OT_REG_EXTRA_MASK)=OT_MMXREG then
                   s:=s+'mmxreg'
                   s:=s+'mmxreg'
                else
                else
-                 if (ot and OT_FPUREG)=OT_FPUREG then
+                 if (ot and OT_REG_EXTRA_MASK)=OT_FPUREG then
                   s:=s+'fpureg'
                   s:=s+'fpureg'
                else
                else
                 if (ot and OT_REGISTER)=OT_REGISTER then
                 if (ot and OT_REGISTER)=OT_REGISTER then
@@ -1595,12 +1599,12 @@ implementation
           for i:=0 to p^.ops-1 do
           for i:=0 to p^.ops-1 do
            begin
            begin
              insot:=p^.optypes[i];
              insot:=p^.optypes[i];
-             if ((insot and OT_XMMRM) = OT_XMMRM) OR
-                ((insot and OT_YMMRM) = OT_YMMRM) then
+             if ((insot and (OT_XMMRM or OT_REG_EXTRA_MASK)) = OT_XMMRM) OR
+                ((insot and (OT_YMMRM or OT_REG_EXTRA_MASK)) = OT_YMMRM) then
              begin
              begin
                if (insot and OT_SIZE_MASK) = 0 then
                if (insot and OT_SIZE_MASK) = 0 then
                begin
                begin
-                 case insot and (OT_XMMRM or OT_YMMRM) of
+                 case insot and (OT_XMMRM or OT_YMMRM or OT_REG_EXTRA_MASK) of
                    OT_XMMRM: insot := insot or OT_BITS128;
                    OT_XMMRM: insot := insot or OT_BITS128;
                    OT_YMMRM: insot := insot or OT_BITS256;
                    OT_YMMRM: insot := insot or OT_BITS256;
                  end;
                  end;
@@ -3066,14 +3070,14 @@ implementation
               end
               end
             else if IF_NEC in insentry^.flags then
             else if IF_NEC in insentry^.flags then
               begin
               begin
-                { the NEC V20/V30 extensions are incompatible with 386+, due to overlapping opcodes }
+              { the NEC V20/V30 extensions are incompatible with 386+, due to overlapping opcodes }
                 if objdata.CPUType>=cpu_386 then
                 if objdata.CPUType>=cpu_386 then
                   Message(asmw_e_instruction_not_supported_by_cpu);
                   Message(asmw_e_instruction_not_supported_by_cpu);
               end
               end
             else if IF_SANDYBRIDGE in insentry^.flags then
             else if IF_SANDYBRIDGE in insentry^.flags then
               begin
               begin
-                { todo: handle these properly }
-              end;
+              { todo: handle these properly }
+            end;
           end;
           end;
 {$endif i8086}
 {$endif i8086}
 
 
@@ -3547,7 +3551,8 @@ implementation
                 if needed_VEX and
                 if needed_VEX and
                   (ops=4) and
                   (ops=4) and
                   (oper[opidx]^.typ=top_reg) and
                   (oper[opidx]^.typ=top_reg) and
-                  (oper[opidx]^.ot and (otf_reg_xmm or otf_reg_ymm)<>0) then
+                  ((oper[opidx]^.ot and OT_REG_EXTRA_MASK)=otf_reg_xmm) or
+                  ((oper[opidx]^.ot and OT_REG_EXTRA_MASK)=otf_reg_ymm) then
                   begin
                   begin
                     bytes[0] := ((getsupreg(oper[opidx]^.reg) and 15) shl 4);
                     bytes[0] := ((getsupreg(oper[opidx]^.reg) and 15) shl 4);
                     objdata.writebytes(bytes,1);
                     objdata.writebytes(bytes,1);
@@ -3725,33 +3730,33 @@ implementation
         fillchar(operation_type_table^,sizeof(toperation_type_table),byte(operand_read));
         fillchar(operation_type_table^,sizeof(toperation_type_table),byte(operand_read));
         for opcode:=low(tasmop) to high(tasmop) do
         for opcode:=low(tasmop) to high(tasmop) do
           with InsProp[opcode] do
           with InsProp[opcode] do
-            begin
+          begin
               if Ch_Rop1 in Ch then
               if Ch_Rop1 in Ch then
-                operation_type_table^[opcode,0]:=operand_read;
+                    operation_type_table^[opcode,0]:=operand_read;
               if Ch_Wop1 in Ch then
               if Ch_Wop1 in Ch then
-                operation_type_table^[opcode,0]:=operand_write;
+                    operation_type_table^[opcode,0]:=operand_write;
               if [Ch_RWop1,Ch_Mop1]*Ch<>[] then
               if [Ch_RWop1,Ch_Mop1]*Ch<>[] then
-                operation_type_table^[opcode,0]:=operand_readwrite;
+                    operation_type_table^[opcode,0]:=operand_readwrite;
               if Ch_Rop2 in Ch then
               if Ch_Rop2 in Ch then
-                operation_type_table^[opcode,1]:=operand_read;
+                    operation_type_table^[opcode,1]:=operand_read;
               if Ch_Wop2 in Ch then
               if Ch_Wop2 in Ch then
-                operation_type_table^[opcode,1]:=operand_write;
+                    operation_type_table^[opcode,1]:=operand_write;
               if [Ch_RWop2,Ch_Mop2]*Ch<>[] then
               if [Ch_RWop2,Ch_Mop2]*Ch<>[] then
-                operation_type_table^[opcode,1]:=operand_readwrite;
+                    operation_type_table^[opcode,1]:=operand_readwrite;
               if Ch_Rop3 in Ch then
               if Ch_Rop3 in Ch then
-                operation_type_table^[opcode,2]:=operand_read;
+                    operation_type_table^[opcode,2]:=operand_read;
               if Ch_Wop3 in Ch then
               if Ch_Wop3 in Ch then
-                operation_type_table^[opcode,2]:=operand_write;
+                    operation_type_table^[opcode,2]:=operand_write;
               if [Ch_RWop3,Ch_Mop3]*Ch<>[] then
               if [Ch_RWop3,Ch_Mop3]*Ch<>[] then
-                operation_type_table^[opcode,2]:=operand_readwrite;
+                    operation_type_table^[opcode,2]:=operand_readwrite;
               if Ch_Rop4 in Ch then
               if Ch_Rop4 in Ch then
                 operation_type_table^[opcode,3]:=operand_read;
                 operation_type_table^[opcode,3]:=operand_read;
               if Ch_Wop4 in Ch then
               if Ch_Wop4 in Ch then
                 operation_type_table^[opcode,3]:=operand_write;
                 operation_type_table^[opcode,3]:=operand_write;
               if [Ch_RWop4,Ch_Mop4]*Ch<>[] then
               if [Ch_RWop4,Ch_Mop4]*Ch<>[] then
                 operation_type_table^[opcode,3]:=operand_readwrite;
                 operation_type_table^[opcode,3]:=operand_readwrite;
-            end;
-      end;
+                end;
+              end;
 
 
 
 
     function taicpu.spilling_get_operation_type(opnr: longint): topertype;
     function taicpu.spilling_get_operation_type(opnr: longint): topertype;
@@ -4056,7 +4061,7 @@ implementation
                   NewRegSize := (insentry^.optypes[j] and OT_SIZE_MASK);
                   NewRegSize := (insentry^.optypes[j] and OT_SIZE_MASK);
                   if NewRegSize = 0 then
                   if NewRegSize = 0 then
                     begin
                     begin
-                      case insentry^.optypes[j] and (OT_MMXREG OR OT_XMMREG OR OT_YMMREG) of
+                      case insentry^.optypes[j] and (OT_MMXREG or OT_XMMREG or OT_YMMREG or OT_REG_EXTRA_MASK) of
                         OT_MMXREG: begin
                         OT_MMXREG: begin
                                      NewRegSize := OT_BITS64;
                                      NewRegSize := OT_BITS64;
                                    end;
                                    end;
@@ -4073,7 +4078,7 @@ implementation
                   end;
                   end;
 
 
                 actRegSize  := actRegSize or NewRegSize;
                 actRegSize  := actRegSize or NewRegSize;
-                actRegTypes := actRegTypes or (insentry^.optypes[j] and (OT_MMXREG OR OT_XMMREG OR OT_YMMREG));
+                actRegTypes := actRegTypes or (insentry^.optypes[j] and (OT_MMXREG or OT_XMMREG or OT_YMMREG or OT_REG_EXTRA_MASK));
                 end
                 end
               else if ((insentry^.optypes[j] and OT_MEMORY) <> 0) then
               else if ((insentry^.optypes[j] and OT_MEMORY) <> 0) then
                 begin
                 begin
@@ -4168,71 +4173,71 @@ implementation
               begin
               begin
                 if (actMemCount=2) and ((AsmOp=A_MOVS) or (AsmOp=A_CMPS)) then
                 if (actMemCount=2) and ((AsmOp=A_MOVS) or (AsmOp=A_CMPS)) then
                   actMemCount:=1;
                   actMemCount:=1;
-                case actMemCount of
-                    0: ; // nothing todo
-                    1: begin
-                         MRefInfo := msiUnkown;
-                         case actRegMemTypes and (OT_MMXRM OR OT_XMMRM OR OT_YMMRM) of
-                           OT_MMXRM: actMemSize := actMemSize or OT_BITS64;
-                           OT_XMMRM: actMemSize := actMemSize or OT_BITS128;
-                           OT_YMMRM: actMemSize := actMemSize or OT_BITS256;
-                         end;
-
-                         case actMemSize of
-                           0: MRefInfo := msiNoSize;
-                           OT_BITS8: MRefInfo := msiMem8;
-                           OT_BITS16: MRefInfo := msiMem16;
-                           OT_BITS32: MRefInfo := msiMem32;
-                           OT_BITS64: MRefInfo := msiMem64;
-                           OT_BITS128: MRefInfo := msiMem128;
-                           OT_BITS256: MRefInfo := msiMem256;
-                           OT_BITS80,
-                           OT_FAR,
-                           OT_NEAR,
-                           OT_SHORT: ; // ignore
-                           else
-                             begin
-                               bitcount := bitcnt(actMemSize);
+            case actMemCount of
+                0: ; // nothing todo
+                1: begin
+                     MRefInfo := msiUnkown;
+                     case actRegMemTypes and (OT_MMXRM or OT_XMMRM or OT_YMMRM or OT_REG_EXTRA_MASK) of
+                       OT_MMXRM: actMemSize := actMemSize or OT_BITS64;
+                       OT_XMMRM: actMemSize := actMemSize or OT_BITS128;
+                       OT_YMMRM: actMemSize := actMemSize or OT_BITS256;
+                     end;
 
 
-                               if bitcount > 1 then MRefInfo := msiMultiple
-                               else InternalError(777203);
-                             end;
+                     case actMemSize of
+                       0: MRefInfo := msiNoSize;
+                       OT_BITS8: MRefInfo := msiMem8;
+                       OT_BITS16: MRefInfo := msiMem16;
+                       OT_BITS32: MRefInfo := msiMem32;
+                       OT_BITS64: MRefInfo := msiMem64;
+                       OT_BITS128: MRefInfo := msiMem128;
+                       OT_BITS256: MRefInfo := msiMem256;
+                       OT_BITS80,
+                       OT_FAR,
+                       OT_NEAR,
+                       OT_SHORT: ; // ignore
+                       else
+                         begin
+                           bitcount := bitcnt(actMemSize);
+
+                           if bitcount > 1 then MRefInfo := msiMultiple
+                           else InternalError(777203);
                          end;
                          end;
+                     end;
 
 
-                         if InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize = msiUnkown then
-                           begin
-                             InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize := MRefInfo;
-                           end
-                         else if InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize <> MRefInfo then
-                           begin
-                             with InsTabMemRefSizeInfoCache^[AsmOp] do
-                             begin
-                               if ((MemRefSize = msiMem8)        OR (MRefInfo = msiMem8))   then MemRefSize := msiMultiple8
-                               else if ((MemRefSize = msiMem16)  OR (MRefInfo = msiMem16))  then MemRefSize := msiMultiple16
-                               else if ((MemRefSize = msiMem32)  OR (MRefInfo = msiMem32))  then MemRefSize := msiMultiple32
-                               else if ((MemRefSize = msiMem64)  OR (MRefInfo = msiMem64))  then MemRefSize := msiMultiple64
-                               else if ((MemRefSize = msiMem128) OR (MRefInfo = msiMem128)) then MemRefSize := msiMultiple128
-                               else if ((MemRefSize = msiMem256) OR (MRefInfo = msiMem256)) then MemRefSize := msiMultiple256
-                               else MemRefSize := msiMultiple;
-                             end;
+                     if InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize = msiUnkown then
+                       begin
+                         InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize := MRefInfo;
+                       end
+                     else if InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize <> MRefInfo then
+                       begin
+                         with InsTabMemRefSizeInfoCache^[AsmOp] do
+                         begin
+                           if ((MemRefSize = msiMem8)        OR (MRefInfo = msiMem8))   then MemRefSize := msiMultiple8
+                           else if ((MemRefSize = msiMem16)  OR (MRefInfo = msiMem16))  then MemRefSize := msiMultiple16
+                           else if ((MemRefSize = msiMem32)  OR (MRefInfo = msiMem32))  then MemRefSize := msiMultiple32
+                           else if ((MemRefSize = msiMem64)  OR (MRefInfo = msiMem64))  then MemRefSize := msiMultiple64
+                           else if ((MemRefSize = msiMem128) OR (MRefInfo = msiMem128)) then MemRefSize := msiMultiple128
+                           else if ((MemRefSize = msiMem256) OR (MRefInfo = msiMem256)) then MemRefSize := msiMultiple256
+                           else MemRefSize := msiMultiple;
                          end;
                          end;
+                     end;
 
 
-                         if actRegCount > 0 then
-                           begin
-                             case actRegTypes and (OT_MMXREG or OT_XMMREG or OT_YMMREG) of
-                               OT_MMXREG: RegMMXSizeMask := RegMMXSizeMask or actMemSize;
-                               OT_XMMREG: RegXMMSizeMask := RegXMMSizeMask or actMemSize;
-                               OT_YMMREG: RegYMMSizeMask := RegYMMSizeMask or actMemSize;
-                                     else begin
-                                            RegMMXSizeMask := not(0);
-                                            RegXMMSizeMask := not(0);
-                                            RegYMMSizeMask := not(0);
-                                          end;
-                             end;
-                           end;
+                     if actRegCount > 0 then
+                       begin
+                         case actRegTypes and (OT_MMXREG or OT_XMMREG or OT_YMMREG or OT_REG_EXTRA_MASK) of
+                           OT_MMXREG: RegMMXSizeMask := RegMMXSizeMask or actMemSize;
+                           OT_XMMREG: RegXMMSizeMask := RegXMMSizeMask or actMemSize;
+                           OT_YMMREG: RegYMMSizeMask := RegYMMSizeMask or actMemSize;
+                                 else begin
+                                        RegMMXSizeMask := not(0);
+                                        RegXMMSizeMask := not(0);
+                                        RegYMMSizeMask := not(0);
+                                      end;
+                         end;
                        end;
                        end;
-                  else InternalError(777202);
-                end;
+                   end;
+              else InternalError(777202);
+            end;
               end;
               end;
 
 
             inc(insentry);
             inc(insentry);