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

View File

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

View File

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

View File

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