mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-21 14:09:16 +02:00
- 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:
parent
8a0adafa43
commit
42d251da1c
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user