浏览代码

- 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 10 年之前
父节点
当前提交
42d251da1c
共有 4 个文件被更改,包括 23 次插入84 次删除
  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 }
   RPNMax = 10;             { I think you only need 4, but just to be safe }
   OpMax  = 25;
   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;
 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
       and concats it to the passed list. The newly created item is returned if the
       instruction was valid, otherwise nil is returned }
       instruction was valid, otherwise nil is returned }
     function ConcatInstruction(p:TAsmList) : tai;virtual;
     function ConcatInstruction(p:TAsmList) : tai;virtual;
-    Procedure Swapoperands;
   end;
   end;
 
 
   {---------------------------------------------------------------------}
   {---------------------------------------------------------------------}
@@ -1030,44 +1022,6 @@ Begin
 end;
 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;
   function TInstruction.ConcatInstruction(p:TAsmList) : tai;
     var
     var
       ai   : taicpu;
       ai   : taicpu;

+ 3 - 19
compiler/x86/rax86.pas

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

+ 0 - 4
compiler/x86/rax86att.pas

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

+ 20 - 15
compiler/x86/rax86int.pas

@@ -1973,6 +1973,7 @@ Unit Rax86int;
         operandnum : longint;
         operandnum : longint;
         is_far_const:boolean;
         is_far_const:boolean;
         i:byte;
         i:byte;
+        tmp: toperand;
       begin
       begin
         PrefixOp:=A_None;
         PrefixOp:=A_None;
         OverrideOp:=A_None;
         OverrideOp:=A_None;
@@ -1982,7 +1983,6 @@ Unit Rax86int;
           if is_prefix(actopcode) then
           if is_prefix(actopcode) then
             with instr do
             with instr do
               begin
               begin
-                OpOrder:=op_intel;
                 PrefixOp:=ActOpcode;
                 PrefixOp:=ActOpcode;
                 opcode:=ActOpcode;
                 opcode:=ActOpcode;
                 condition:=ActCondition;
                 condition:=ActCondition;
@@ -1994,7 +1994,6 @@ Unit Rax86int;
            if is_override(actopcode) then
            if is_override(actopcode) then
              with instr do
              with instr do
                begin
                begin
-                 OpOrder:=op_intel;
                  OverrideOp:=ActOpcode;
                  OverrideOp:=ActOpcode;
                  opcode:=ActOpcode;
                  opcode:=ActOpcode;
                  condition:=ActCondition;
                  condition:=ActCondition;
@@ -2018,7 +2017,6 @@ Unit Rax86int;
         { Fill the instr object with the current state }
         { Fill the instr object with the current state }
         with instr do
         with instr do
           begin
           begin
-            OpOrder:=op_intel;
             Opcode:=ActOpcode;
             Opcode:=ActOpcode;
             condition:=ActCondition;
             condition:=ActCondition;
             opsize:=ActOpsize;
             opsize:=ActOpsize;
@@ -2045,15 +2043,13 @@ Unit Rax86int;
 {$endif x86_64}
 {$endif x86_64}
         ;
         ;
         { We are reading operands, so opcode will be an AS_ID }
         { 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;
         is_far_const:=false;
         Consume(AS_OPCODE);
         Consume(AS_OPCODE);
         { Zero operand opcode ?  }
         { Zero operand opcode ?  }
         if actasmtoken in [AS_SEPARATOR,AS_END] then
         if actasmtoken in [AS_SEPARATOR,AS_END] then
-         begin
-           operandnum:=0;
-           exit;
-         end;
+          exit;
         { Read Operands }
         { Read Operands }
         repeat
         repeat
           case actasmtoken of
           case actasmtoken of
@@ -2065,10 +2061,13 @@ Unit Rax86int;
             { Operand delimiter }
             { Operand delimiter }
             AS_COMMA :
             AS_COMMA :
               begin
               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)
                   Message(asmr_e_too_many_operands)
                 else
                 else
-                  Inc(operandnum);
+                  Dec(operandnum);
                 Consume(AS_COMMA);
                 Consume(AS_COMMA);
               end;
               end;
 
 
@@ -2076,10 +2075,10 @@ Unit Rax86int;
             AS_COLON:
             AS_COLON:
               begin
               begin
                 is_far_const:=true;
                 is_far_const:=true;
-                if operandnum>1 then
+                if operandnum<max_operands then
                   message(asmr_e_too_many_operands)
                   message(asmr_e_too_many_operands)
                 else
                 else
-                  inc(operandnum);
+                  dec(operandnum);
                 consume(AS_COLON);
                 consume(AS_COLON);
               end;
               end;
 
 
@@ -2109,6 +2108,15 @@ Unit Rax86int;
               BuildOperand(instr.Operands[operandnum] as tx86operand,false);
               BuildOperand(instr.Operands[operandnum] as tx86operand,false);
           end; { end case }
           end; { end case }
         until false;
         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;
         instr.ops:=operandnum;
         { Check operands }
         { Check operands }
         for i:=1 to operandnum do
         for i:=1 to operandnum do
@@ -2296,9 +2304,6 @@ Unit Rax86int;
               BuildOpcode(instr);
               BuildOpcode(instr);
               with instr do
               with instr do
                 begin
                 begin
-                  { We need AT&T style operands }
-                  Swapoperands;
-                  { Must be done with args in ATT order }
                   CheckNonCommutativeOpcodes;
                   CheckNonCommutativeOpcodes;
                   AddReferenceSizes;
                   AddReferenceSizes;
                   SetInstructionOpsize;
                   SetInstructionOpsize;