- 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 -
This commit is contained in:
sergei 2014-11-16 16:37:26 +00:00
parent 8a0adafa43
commit 42d251da1c
4 changed files with 23 additions and 84 deletions

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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 exit;
operandnum:=0;
exit;
end;
{ 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;