Browse Source

bugfix assembler-reader att operandsize prefix and more

git-svn-id: branches/tg74/avx1@22661 -
tg74 12 years ago
parent
commit
b65941f89a
3 changed files with 93 additions and 18 deletions
  1. 25 4
      compiler/x86/aasmcpu.pas
  2. 37 12
      compiler/x86/rax86.pas
  3. 31 2
      compiler/x86/rax86att.pas

+ 25 - 4
compiler/x86/aasmcpu.pas

@@ -222,7 +222,9 @@ interface
         Ch : Array[1..MaxInsChanges] of TInsChange;
       end;
 
-      TMemRefSizeInfo = (msiUnkown, msiUnsupported, msiNoSize, msiMultiple,
+      TMemRefSizeInfo = (msiUnkown, msiUnsupported, msiNoSize,
+                         msiMultiple, msiMultiple8, msiMultiple16, msiMultiple32,
+                         msiMultiple64, msiMultiple128, msiMultiple256,
                          msiMemRegSize, msiMemRegx64y128, msiMemRegx64y256,
                          msiMem8, msiMem16, msiMem32, msiMem64, msiMem128, msiMem256);
 
@@ -233,7 +235,14 @@ interface
         ExistsSSEAVX: boolean;
         ConstSize   : TConstSizeInfo;
       end;
+
     const
+      MemRefMultiples: set of TMemRefSizeInfo = [msiMultiple, msiMultiple8,
+                                                 msiMultiple16, msiMultiple32,
+                                                 msiMultiple64, msiMultiple128,
+                                                 msiMultiple256];
+
+
       InsProp : array[tasmop] of TInsProp =
 {$ifdef x86_64}
         {$i x8664pro.inc}
@@ -1278,7 +1287,7 @@ implementation
               end;
           end;
 
-        if (InsTabMemRefSizeInfoCache^[opcode].MemRefSize = msiMultiple) and
+        if (InsTabMemRefSizeInfoCache^[opcode].MemRefSize in MemRefMultiples) and
            (InsTabMemRefSizeInfoCache^[opcode].ExistsSSEAVX) then
         begin
           for i:=0 to p^.ops-1 do
@@ -3150,7 +3159,19 @@ implementation
                      end
                      else if InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize <> MRefInfo then
                      begin
-                       InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize := msiMultiple;
+                       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;
 
                      if actRegCount > 0 then
@@ -3173,7 +3194,7 @@ implementation
             inc(insentry);
           end;
 
-          if (InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize = msiMultiple) and
+          if (InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize in MemRefMultiples) and
              (InsTabMemRefSizeInfoCache^[AsmOp].ExistsSSEAVX)then
           begin
             case RegXMMSizeMask of

+ 37 - 12
compiler/x86/rax86.pas

@@ -52,7 +52,7 @@ type
     opsize  : topsize;
     constructor Create(optype : tcoperand);override;
     { Operand sizes }
-    procedure AddReferenceSizes;
+    procedure AddReferenceSizes; virtual;
     procedure SetInstructionOpsize;
     procedure CheckOperandSizes;
     procedure CheckNonCommutativeOpcodes;
@@ -352,6 +352,7 @@ begin
   ExistsConstNoSize  := false;
   ExistsLocalSymSize := false;
 
+  // EXIST A MEMORY- OR CONSTANT-OPERAND WITHOUT SIZE ?
   for i := 1 to ops do
   begin
     if operands[i].Opr.Typ in [OPR_REFERENCE, OPR_LOCAL] then
@@ -375,17 +376,23 @@ begin
     end;
   end;
 
+  // ONLY SUPPORTED OPCODES WITH SSE- OR AVX-REGISTERS
   if (ExistsMemRef) and
      (MemRefInfo(opcode).ExistsSSEAVX) then
   begin
+    // 1. WE HAVE AN SSE- OR AVX-OPCODE WITH MEMORY OPERAND
     if (not(ExistsMemRefNoSize)) or
        (ExistsLocalSymSize) then
     begin
+      // 2. WE KNOWN THE MEMORYSIZE OF THE MEMORY-OPERAND OR WE CAN
+      //    CALC THE MEMORYSIZE
+
+      // 3. CALC THE SIZE OF THE MEMORYOPERAND BY OPCODE-DEFINITION
+      // 4. COMPARE THE SIZE FROM OPCODE-DEFINITION AND THE REAL MEMORY-OPERAND-SIZE
+
       // - validate memory-reference-size
       for i := 1 to ops do
       begin
-        //if (operands[i].Opr.Typ in [OPR_REFERENCE, OPR_LOCAL]) and
-        //   (tx86operand(operands[i]).opsize <> S_NO) then
         if (operands[i].Opr.Typ in [OPR_REFERENCE, OPR_LOCAL]) then
         begin
           memrefsize := -1;
@@ -422,6 +429,12 @@ begin
 
           if memrefsize > -1 then
           begin
+            // CALC REAL-MEMORY-OPERAND-SIZE AND A POSSIBLE OFFSET
+
+            // OFFSET:
+            // e.g. PAND  XMM0, [RAX + 16] =>> OFFSET = 16 BYTES
+            //      PAND  XMM0, [RAX + a.b + 10] =>> OFFSET = 10 BYTES   (a = record-variable)
+
             memopsize := 0;
             case operands[i].opr.typ of
                   OPR_LOCAL: memopsize := operands[i].opr.localvarsize * 8;
@@ -487,27 +500,39 @@ begin
         case operands[i].Opr.Typ of
           OPR_REFERENCE:
                 case MemRefInfo(opcode).MemRefSize of
-                    msiMem8: begin
-                                tx86operand(operands[i]).opsize := S_B;
-                                tx86operand(operands[i]).size   := OS_8;
-                              end;
-                   msiMem16: begin
+                    msiMem8,
+                    msiMultiple8:
+                             begin
+                               tx86operand(operands[i]).opsize := S_B;
+                               tx86operand(operands[i]).size   := OS_8;
+                             end;
+                   msiMem16,
+                   msiMultiple16:
+                             begin
                                tx86operand(operands[i]).opsize := S_W;
                                tx86operand(operands[i]).size   := OS_16;
                              end;
-                   msiMem32: begin
+                   msiMem32,
+                   msiMultiple32:
+                             begin
                                tx86operand(operands[i]).opsize := S_L;
                                tx86operand(operands[i]).size   := OS_32;
                              end;
-                   msiMem64: begin
+                   msiMem64,
+                   msiMultiple64:
+                             begin
                                tx86operand(operands[i]).opsize := S_Q;
                                tx86operand(operands[i]).size   := OS_M64;
                              end;
-                  msiMem128: begin
+                  msiMem128,
+                  msiMultiple128:
+                             begin
                                tx86operand(operands[i]).opsize := S_XMM;
                                tx86operand(operands[i]).size   := OS_M128;
                              end;
-                  msiMem256: begin
+                  msiMem256,
+                  msiMultiple256:
+                             begin
                                tx86operand(operands[i]).opsize := S_YMM;
                                tx86operand(operands[i]).size   := OS_M256;
                                opsize := S_YMM;

+ 31 - 2
compiler/x86/rax86att.pas

@@ -27,9 +27,12 @@ Interface
 
   uses
     cpubase,
-    raatt,rax86;
+    raatt,rax86, rautils;
 
   type
+
+    { tx86attreader }
+
     tx86attreader = class(tattreader)
       ActOpsize : topsize;
       function is_asmopcode(const s: string):boolean;override;
@@ -42,7 +45,10 @@ Interface
       procedure MaybeGetPICModifier(var oper: tx86operand);
     end;
 
+    { Tx86attInstruction }
+
     Tx86attInstruction = class(Tx86Instruction)
+      procedure AddReferenceSizes; override;
       procedure FixupOpcode;override;
     end;
 
@@ -62,12 +68,34 @@ Implementation
       scanner,
       procinfo,
       itcpugas,
-      rabase,rautils,
+      rabase,
       cgbase
       ;
 
     { Tx86attInstruction }
 
+
+    procedure Tx86attInstruction.AddReferenceSizes;
+    var
+      i: integer;
+    begin
+      if (Opsize <> S_NO) and
+         (MemRefInfo(opcode).ExistsSSEAVX) and
+         (MemRefInfo(opcode).MemRefSize in MemRefMultiples) then
+      begin
+        for i := 1 to ops do
+        begin
+          if operands[i].Opr.Typ in [OPR_REFERENCE, OPR_LOCAL] then
+          begin
+            if (tx86operand(operands[i]).opsize = S_NO) then
+             tx86operand(operands[i]).opsize := Opsize;
+          end;
+        end;
+      end;
+
+      inherited AddReferenceSizes;
+    end;
+
     procedure Tx86attInstruction.FixupOpcode;
       begin
         if (OpOrder=op_intel) then
@@ -929,4 +957,5 @@ Implementation
       end;
 
 
+
 end.