mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-22 06:09:14 +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 }
|
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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user