Parcourir la source

- x86 assembler readers: cleaned out operand swapping code. Operands of TInstruction are kept in AT&T order, Intel reader attaches operands right-to-left. It was effectively the same way before the change (except Intel reader attaching operands left-to-right, followed by a single swap), operand order checks all over the place were just reducing readability.

git-svn-id: trunk@29081 -
sergei il y a 10 ans
Parent
commit
42d251da1c
4 fichiers modifiés avec 23 ajouts et 84 suppressions
  1. 0 46
      compiler/rautils.pas
  2. 3 19
      compiler/x86/rax86.pas
  3. 0 4
      compiler/x86/rax86att.pas
  4. 20 15
      compiler/x86/rax86int.pas

+ 0 - 46
compiler/rautils.pas

@@ -34,13 +34,6 @@ Const
   RPNMax = 10;             { I think you only need 4, but just to be safe }
   OpMax  = 25;
 
-{$if max_operands = 2}
-  {$define MAX_OPER_2}
-{$endif}
-{$if max_operands = 3}
-  {$define MAX_OPER_3}
-{$endif}
-
 Function SearchLabel(const s: string; var hl: tasmlabel;emit:boolean): boolean;
 
 
@@ -110,7 +103,6 @@ type
       and concats it to the passed list. The newly created item is returned if the
       instruction was valid, otherwise nil is returned }
     function ConcatInstruction(p:TAsmList) : tai;virtual;
-    Procedure Swapoperands;
   end;
 
   {---------------------------------------------------------------------}
@@ -1030,44 +1022,6 @@ Begin
 end;
 
 
-  Procedure TInstruction.Swapoperands;
-    Var
-      p : toperand;
-    Begin
-      case ops of
-        0,1:
-          ;
-        2 : begin
-              { 0,1 -> 1,0 }
-              p:=Operands[1];
-              Operands[1]:=Operands[2];
-              Operands[2]:=p;
-            end;
-{$ifndef MAX_OPER_2}
-        3 : begin
-              { 0,1,2 -> 2,1,0 }
-              p:=Operands[1];
-              Operands[1]:=Operands[3];
-              Operands[3]:=p;
-            end;
-{$ifndef MAX_OPER_3}
-        4 : begin
-              { 0,1,2,3 -> 3,2,1,0 }
-              p:=Operands[1];
-              Operands[1]:=Operands[4];
-              Operands[4]:=p;
-              p:=Operands[2];
-              Operands[2]:=Operands[3];
-              Operands[3]:=p;
-            end;
-{$endif}
-{$endif}
-        else
-          internalerror(201108142);
-      end;
-    end;
-
-
   function TInstruction.ConcatInstruction(p:TAsmList) : tai;
     var
       ai   : taicpu;

+ 3 - 19
compiler/x86/rax86.pas

@@ -47,8 +47,9 @@ type
     Function CheckOperand: boolean; override;
   end;
 
+  { Operands are always in AT&T order.
+    Intel reader attaches them right-to-left, then shifts to start with 1 }
   Tx86Instruction=class(TInstruction)
-    OpOrder : TOperandOrder;
     opsize  : topsize;
     constructor Create(optype : tcoperand);override;
     { Operand sizes }
@@ -56,7 +57,6 @@ type
     procedure SetInstructionOpsize;
     procedure CheckOperandSizes;
     procedure CheckNonCommutativeOpcodes;
-    procedure SwapOperands;
     { Additional actions required by specific reader }
     procedure FixupOpcode;virtual;
     { opcode adding }
@@ -295,16 +295,6 @@ begin
 end;
 
 
-procedure Tx86Instruction.SwapOperands;
-begin
-  Inherited SwapOperands;
-  { mark the correct order }
-  if OpOrder=op_intel then
-    OpOrder:=op_att
-  else
-    OpOrder:=op_intel;
-end;
-
 const
 {$ifdef x86_64}
   topsize2memsize: array[topsize] of integer =
@@ -804,8 +794,6 @@ procedure Tx86Instruction.SetInstructionOpsize;
 begin
   if opsize<>S_NO then
    exit;
-  if (OpOrder=op_intel) then
-    SwapOperands;
   case ops of
     0 : ;
     1 :
@@ -941,8 +929,6 @@ end;
   but before swapping in the NASM and TASM writers PM }
 procedure Tx86Instruction.CheckNonCommutativeOpcodes;
 begin
-  if (OpOrder=op_intel) then
-    SwapOperands;
   if (
       (ops=2) and
       (operands[1].opr.typ=OPR_REGISTER) and
@@ -1002,8 +988,6 @@ var
   ai   : taicpu;
 begin
   ConcatInstruction:=nil;
-  if (OpOrder=op_intel) then
-    SwapOperands;
 
   ai:=nil;
   for i:=1 to Ops do
@@ -1164,7 +1148,7 @@ begin
 
   ai:=taicpu.op_none(opcode,siz);
   ai.fileinfo:=filepos;
-  ai.SetOperandOrder(OpOrder);
+  ai.SetOperandOrder(op_att);
   ai.Ops:=Ops;
   ai.Allocate_oper(Ops);
   for i:=1 to Ops do

+ 0 - 4
compiler/x86/rax86att.pas

@@ -98,9 +98,6 @@ Implementation
 
     procedure Tx86attInstruction.FixupOpcode;
       begin
-        if (OpOrder=op_intel) then
-          SwapOperands;
-
         case opcode of
           A_MOVQ:
             begin
@@ -973,7 +970,6 @@ Implementation
         instr : Tx86Instruction;
       begin
         instr:=Tx86attInstruction.Create(Tx86Operand);
-        instr.OpOrder:=op_att;
         BuildOpcode(instr);
         instr.AddReferenceSizes;
         instr.SetInstructionOpsize;

+ 20 - 15
compiler/x86/rax86int.pas

@@ -1973,6 +1973,7 @@ Unit Rax86int;
         operandnum : longint;
         is_far_const:boolean;
         i:byte;
+        tmp: toperand;
       begin
         PrefixOp:=A_None;
         OverrideOp:=A_None;
@@ -1982,7 +1983,6 @@ Unit Rax86int;
           if is_prefix(actopcode) then
             with instr do
               begin
-                OpOrder:=op_intel;
                 PrefixOp:=ActOpcode;
                 opcode:=ActOpcode;
                 condition:=ActCondition;
@@ -1994,7 +1994,6 @@ Unit Rax86int;
            if is_override(actopcode) then
              with instr do
                begin
-                 OpOrder:=op_intel;
                  OverrideOp:=ActOpcode;
                  opcode:=ActOpcode;
                  condition:=ActCondition;
@@ -2018,7 +2017,6 @@ Unit Rax86int;
         { Fill the instr object with the current state }
         with instr do
           begin
-            OpOrder:=op_intel;
             Opcode:=ActOpcode;
             condition:=ActCondition;
             opsize:=ActOpsize;
@@ -2045,15 +2043,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
@@ -2065,10 +2061,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;
 
@@ -2076,10 +2075,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;
 
@@ -2109,6 +2108,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
@@ -2296,9 +2304,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;