Browse Source

merge with trunk

git-svn-id: branches/tg74/avx2@29648 -
tg74 10 years ago
parent
commit
6cad24d373
2 changed files with 102 additions and 101 deletions
  1. 69 71
      compiler/x86/aasmcpu.pas
  2. 33 30
      compiler/x86/rax86int.pas

+ 69 - 71
compiler/x86/aasmcpu.pas

@@ -1265,7 +1265,7 @@ implementation
                     assembler }
                 end;
               else
-                internalerror(200402261);
+                internalerror(200402266);
             end;
           end;
       end;
@@ -3412,38 +3412,38 @@ implementation
               begin
                 inc(actRegCount);
 
-                NewRegSize := (insentry^.optypes[j] and OT_SIZE_MASK);
-                if NewRegSize = 0 then
-                begin
-                  case insentry^.optypes[j] and (OT_MMXREG OR OT_XMMREG OR OT_YMMREG) of
-                    OT_MMXREG: begin
-                                 NewRegSize := OT_BITS64;
-                               end;
-                    OT_XMMREG: begin
-                                 NewRegSize := OT_BITS128;
-                                 InsTabMemRefSizeInfoCache^[AsmOp].ExistsSSEAVX := true;
-                               end;
-                    OT_YMMREG: begin
-                                 NewRegSize := OT_BITS256;
-                                 InsTabMemRefSizeInfoCache^[AsmOp].ExistsSSEAVX := true;
-                               end;
-                          else NewRegSize := not(0);
+                  NewRegSize := (insentry^.optypes[j] and OT_SIZE_MASK);
+                  if NewRegSize = 0 then
+                    begin
+                      case insentry^.optypes[j] and (OT_MMXREG OR OT_XMMREG OR OT_YMMREG) of
+                        OT_MMXREG: begin
+                                     NewRegSize := OT_BITS64;
+                                   end;
+                        OT_XMMREG: begin
+                                     NewRegSize := OT_BITS128;
+                                     InsTabMemRefSizeInfoCache^[AsmOp].ExistsSSEAVX := true;
+                                   end;
+                        OT_YMMREG: begin
+                                     NewRegSize := OT_BITS256;
+                                     InsTabMemRefSizeInfoCache^[AsmOp].ExistsSSEAVX := true;
+                                   end;
+                              else NewRegSize := not(0);
+                      end;
                   end;
-                end;
 
                 actRegSize  := actRegSize or NewRegSize;
                 actRegTypes := actRegTypes or (insentry^.optypes[j] and (OT_MMXREG OR OT_XMMREG OR OT_YMMREG));
-              end
+                end
               else if ((insentry^.optypes[j] and OT_MEMORY) <> 0) then
-              begin
-                inc(actMemCount);
-
-                actMemSize    := actMemSize or (insentry^.optypes[j] and OT_SIZE_MASK);
-                if (insentry^.optypes[j] and OT_REGMEM) = OT_REGMEM then
                 begin
-                  actRegMemTypes  := actRegMemTypes or insentry^.optypes[j];
-                end;
-              end
+                  inc(actMemCount);
+
+                  actMemSize:=actMemSize or (insentry^.optypes[j] and OT_SIZE_MASK);
+                  if (insentry^.optypes[j] and OT_REGMEM) = OT_REGMEM then
+                    begin
+                      actRegMemTypes  := actRegMemTypes or insentry^.optypes[j];
+                    end;
+                end
               else if ((insentry^.optypes[j] and OT_IMMEDIATE) = OT_IMMEDIATE) then
               begin
                 inc(actConstCount);
@@ -3455,12 +3455,12 @@ implementation
             if actConstCount > 0 then
             begin
               case actConstSize of
-                        0: SConstInfo := csiNoSize;
-                 OT_BITS8: SConstInfo := csiMem8;
+                0: SConstInfo := csiNoSize;
+                OT_BITS8: SConstInfo := csiMem8;
                 OT_BITS16: SConstInfo := csiMem16;
                 OT_BITS32: SConstInfo := csiMem32;
                 OT_BITS64: SConstInfo := csiMem64;
-                      else SConstInfo := csiMultiple;
+                else SConstInfo := csiMultiple;
               end;
 
               if InsTabMemRefSizeInfoCache^[AsmOp].ConstSize = csiUnkown then
@@ -3535,59 +3535,57 @@ implementation
                      end;
 
                      case actMemSize of
-                                0: MRefInfo := msiNoSize;
-                         OT_BITS8: MRefInfo := msiMem8;
-                        OT_BITS16: MRefInfo := msiMem16;
-                        OT_BITS32: MRefInfo := msiMem32;
-                        OT_BITS64: MRefInfo := msiMem64;
+                       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;
+                       OT_FAR,
+                       OT_NEAR,
+                       OT_SHORT: ; // ignore
+                       else
+                         begin
+                           bitcount := bitcnt(actMemSize);
+
+                           if bitcount > 1 then MRefInfo := msiMultiple
+                           else InternalError(777203);
+                         end;
                      end;
 
                      if InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize = msiUnkown then
-                     begin
-                       InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize := MRefInfo;
-                     end
+                       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;
+                         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
-                     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;
+                       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;
-                     end;
                    end;
               else InternalError(777202);
             end;

+ 33 - 30
compiler/x86/rax86int.pas

@@ -65,7 +65,7 @@ Unit Rax86int;
          procedure BuildRecordOffsetSize(const expr: string;var offset:aint;var size:aint; var mangledname: string; needvmtofs: boolean);
          procedure BuildConstSymbolExpression(needofs,isref,startingminus:boolean;var value:aint;var asmsym:string;var asmsymtyp:TAsmsymtype);
          function BuildConstExpression:aint;
-         function BuildRefConstExpression:aint;
+         function BuildRefConstExpression(startingminus:boolean=false):aint;
          procedure BuildReference(oper : tx86operand);
          procedure BuildOperand(oper: tx86operand;istypecast:boolean);
          procedure BuildConstantOperand(oper: tx86operand);
@@ -1141,13 +1141,13 @@ Unit Rax86int;
       end;
 
 
-    Function tx86intreader.BuildRefConstExpression:aint;
+    Function tx86intreader.BuildRefConstExpression(startingminus:boolean):aint;
       var
         l : aint;
         hs : string;
         hssymtyp : TAsmsymtype;
       begin
-        BuildConstSymbolExpression(false,true,false,l,hs,hssymtyp);
+        BuildConstSymbolExpression(false,true,startingminus,l,hs,hssymtyp);
         if hs<>'' then
          Message(asmr_e_relocatable_symbol_not_allowed);
         BuildRefConstExpression:=l;
@@ -1190,7 +1190,8 @@ Unit Rax86int;
                    (SearchIConstant(actasmpattern,l) or
                     SearchRecordType(actasmpattern)) then
                  begin
-                   l:=BuildRefConstExpression;
+                   l:=BuildRefConstExpression(negative);
+                   negative:=false;   { "l" was negated if necessary }
                    GotPlus:=(prevasmtoken=AS_PLUS);
                    GotStar:=(prevasmtoken=AS_STAR);
                    case oper.opr.typ of
@@ -1198,23 +1199,15 @@ Unit Rax86int;
                        begin
                          if GotStar then
                            Message(asmr_e_invalid_reference_syntax);
-                         if negative then
-                           Dec(oper.opr.localsymofs,l)
-                         else
-                           Inc(oper.opr.localsymofs,l);
+                         Inc(oper.opr.localsymofs,l);
                        end;
                      OPR_REFERENCE :
                        begin
                          if GotStar then
                           oper.opr.ref.scalefactor:=l
                          else
-                          begin
-                            if negative then
-                              Dec(oper.opr.ref.offset,l)
-                            else
-                              Inc(oper.opr.ref.offset,l);
-                          end;
-                        end;
+                           Inc(oper.opr.ref.offset,l);
+                       end;
                    end;
                  end
                 else
@@ -1427,6 +1420,11 @@ Unit Rax86int;
                     begin
                       if (oper.opr.localindexreg<>NR_NO) then
                         Message(asmr_e_multiple_index);
+{$ifdef x86_64}
+                      { Locals/parameters cannot be accessed RIP-relative. Need a dedicated error message here? }
+                      if (hreg=NR_RIP) then
+                        Message(asmr_e_no_local_or_para_allowed);
+{$endif x86_64}
                       oper.opr.localindexreg:=hreg;
                       if scale<>0 then
                         begin
@@ -1981,6 +1979,7 @@ Unit Rax86int;
         t: TRegister;
         is_far_const:boolean;
         i:byte;
+        tmp: toperand;
       begin
         PrefixOp:=A_None;
         OverrideOp:=A_None;
@@ -1990,7 +1989,6 @@ Unit Rax86int;
           if is_prefix(actopcode) then
             with instr do
               begin
-                OpOrder:=op_intel;
                 PrefixOp:=ActOpcode;
                 opcode:=ActOpcode;
                 condition:=ActCondition;
@@ -2002,7 +2000,6 @@ Unit Rax86int;
            if is_override(actopcode) then
              with instr do
                begin
-                 OpOrder:=op_intel;
                  OverrideOp:=ActOpcode;
                  opcode:=ActOpcode;
                  condition:=ActCondition;
@@ -2026,7 +2023,6 @@ Unit Rax86int;
         { Fill the instr object with the current state }
         with instr do
           begin
-            OpOrder:=op_intel;
             Opcode:=ActOpcode;
             condition:=ActCondition;
             opsize:=ActOpsize;
@@ -2053,15 +2049,13 @@ Unit Rax86int;
 {$endif x86_64}
         ;
         { We are reading operands, so opcode will be an AS_ID }
-        operandnum:=1;
+        { process operands backwards to get them in AT&T order }
+        operandnum:=max_operands;
         is_far_const:=false;
         Consume(AS_OPCODE);
         { Zero operand opcode ?  }
         if actasmtoken in [AS_SEPARATOR,AS_END] then
-         begin
-           operandnum:=0;
-           exit;
-         end;
+          exit;
         { Read Operands }
         repeat
           case actasmtoken of
@@ -2073,10 +2067,13 @@ Unit Rax86int;
             { Operand delimiter }
             AS_COMMA :
               begin
-                if operandnum > Max_Operands then
+                { should have something before the comma }
+                if instr.operands[operandnum].opr.typ=OPR_NONE then
+                  Message(asmr_e_syntax_error);
+                if operandnum <= 1 then
                   Message(asmr_e_too_many_operands)
                 else
-                  Inc(operandnum);
+                  Dec(operandnum);
                 Consume(AS_COMMA);
               end;
 
@@ -2084,10 +2081,10 @@ Unit Rax86int;
             AS_COLON:
               begin
                 is_far_const:=true;
-                if operandnum>1 then
+                if operandnum<max_operands then
                   message(asmr_e_too_many_operands)
                 else
-                  inc(operandnum);
+                  dec(operandnum);
                 consume(AS_COLON);
               end;
 
@@ -2117,6 +2114,15 @@ Unit Rax86int;
               BuildOperand(instr.Operands[operandnum] as tx86operand,false);
           end; { end case }
         until false;
+
+        { shift operands to start from 1, exchange to make sure they are destroyed correctly }
+        for i:=operandnum to max_operands do
+          begin
+            tmp:=instr.operands[i+1-operandnum];
+            instr.operands[i+1-operandnum]:=instr.operands[i];
+            instr.operands[i]:=tmp;
+          end;
+        operandnum:=(max_operands+1)-operandnum;
         instr.ops:=operandnum;
         { Check operands }
         for i:=1 to operandnum do
@@ -2335,9 +2341,6 @@ Unit Rax86int;
               BuildOpcode(instr);
               with instr do
                 begin
-                  { We need AT&T style operands }
-                  Swapoperands;
-                  { Must be done with args in ATT order }
                   CheckNonCommutativeOpcodes;
                   AddReferenceSizes;
                   SetInstructionOpsize;