mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 02:41:50 +02:00
* Fixed handling of 'movq' instruction by assembler reader, resolves #18205.
git-svn-id: trunk@17497 -
This commit is contained in:
parent
e271595e20
commit
08e895cf7c
@ -57,6 +57,8 @@ type
|
|||||||
procedure CheckOperandSizes;
|
procedure CheckOperandSizes;
|
||||||
procedure CheckNonCommutativeOpcodes;
|
procedure CheckNonCommutativeOpcodes;
|
||||||
procedure SwapOperands;
|
procedure SwapOperands;
|
||||||
|
{ Additional actions required by specific reader }
|
||||||
|
procedure FixupOpcode;virtual;
|
||||||
{ opcode adding }
|
{ opcode adding }
|
||||||
function ConcatInstruction(p : TAsmList) : tai;override;
|
function ConcatInstruction(p : TAsmList) : tai;override;
|
||||||
end;
|
end;
|
||||||
@ -535,6 +537,11 @@ begin
|
|||||||
opcode:=A_FDIVRP;
|
opcode:=A_FDIVRP;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure Tx86Instruction.FixupOpcode;
|
||||||
|
begin
|
||||||
|
{ does nothing by default }
|
||||||
|
end;
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
opcode Adding
|
opcode Adding
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
@ -623,18 +630,6 @@ begin
|
|||||||
siz:=S_FAR;
|
siz:=S_FAR;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$ifdef x86_64}
|
|
||||||
{ Convert movq with at least one general registers or constant to a mov instruction }
|
|
||||||
if (opcode=A_MOVQ) and
|
|
||||||
(ops=2) and
|
|
||||||
(
|
|
||||||
(operands[1].opr.typ=OPR_REGISTER) or
|
|
||||||
(operands[2].opr.typ=OPR_REGISTER) or
|
|
||||||
(operands[1].opr.typ=OPR_CONSTANT)
|
|
||||||
) then
|
|
||||||
opcode:=A_MOV;
|
|
||||||
{$endif x86_64}
|
|
||||||
|
|
||||||
{ GNU AS interprets FDIV without operand differently
|
{ GNU AS interprets FDIV without operand differently
|
||||||
for version 2.9.1 and 2.10
|
for version 2.9.1 and 2.10
|
||||||
we add explicit args to it !! }
|
we add explicit args to it !! }
|
||||||
|
@ -42,6 +42,9 @@ Interface
|
|||||||
procedure MaybeGetPICModifier(var oper: tx86operand);
|
procedure MaybeGetPICModifier(var oper: tx86operand);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Tx86attInstruction = class(Tx86Instruction)
|
||||||
|
procedure FixupOpcode;override;
|
||||||
|
end;
|
||||||
|
|
||||||
Implementation
|
Implementation
|
||||||
|
|
||||||
@ -63,6 +66,37 @@ Implementation
|
|||||||
cgbase
|
cgbase
|
||||||
;
|
;
|
||||||
|
|
||||||
|
{ Tx86attInstruction }
|
||||||
|
|
||||||
|
procedure Tx86attInstruction.FixupOpcode;
|
||||||
|
begin
|
||||||
|
if (OpOrder=op_intel) then
|
||||||
|
SwapOperands;
|
||||||
|
|
||||||
|
case opcode of
|
||||||
|
A_MOVQ:
|
||||||
|
begin
|
||||||
|
{ May be either real 'movq' or a generic 'mov' with 'q' suffix. Convert to mov
|
||||||
|
if source is a constant, or if neither operand is an mmx/xmm register }
|
||||||
|
{$ifdef x86_64}
|
||||||
|
if (ops=2) and
|
||||||
|
(
|
||||||
|
(operands[1].opr.typ=OPR_CONSTANT) or not
|
||||||
|
(
|
||||||
|
((operands[1].opr.typ=OPR_REGISTER) and
|
||||||
|
(getregtype(operands[1].opr.reg) in [R_MMXREGISTER,R_MMREGISTER])) or
|
||||||
|
((operands[2].opr.typ=OPR_REGISTER) and
|
||||||
|
(getregtype(operands[2].opr.reg) in [R_MMXREGISTER,R_MMREGISTER]))
|
||||||
|
)
|
||||||
|
) then
|
||||||
|
opcode:=A_MOV;
|
||||||
|
{$endif x86_64}
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Tx86attReader }
|
||||||
|
|
||||||
procedure tx86attreader.handlepercent;
|
procedure tx86attreader.handlepercent;
|
||||||
var
|
var
|
||||||
len : longint;
|
len : longint;
|
||||||
@ -848,12 +882,13 @@ Implementation
|
|||||||
var
|
var
|
||||||
instr : Tx86Instruction;
|
instr : Tx86Instruction;
|
||||||
begin
|
begin
|
||||||
instr:=Tx86Instruction.Create(Tx86Operand);
|
instr:=Tx86attInstruction.Create(Tx86Operand);
|
||||||
instr.OpOrder:=op_att;
|
instr.OpOrder:=op_att;
|
||||||
BuildOpcode(instr);
|
BuildOpcode(instr);
|
||||||
instr.AddReferenceSizes;
|
instr.AddReferenceSizes;
|
||||||
instr.SetInstructionOpsize;
|
instr.SetInstructionOpsize;
|
||||||
instr.CheckOperandSizes;
|
instr.CheckOperandSizes;
|
||||||
|
instr.FixupOpcode;
|
||||||
instr.ConcatInstruction(curlist);
|
instr.ConcatInstruction(curlist);
|
||||||
instr.Free;
|
instr.Free;
|
||||||
end;
|
end;
|
||||||
|
@ -43,12 +43,13 @@ Unit rax64att;
|
|||||||
var
|
var
|
||||||
instr : Tx86Instruction;
|
instr : Tx86Instruction;
|
||||||
begin
|
begin
|
||||||
instr:=Tx86Instruction.Create(Tx86Operand);
|
instr:=Tx86attInstruction.Create(Tx86Operand);
|
||||||
instr.OpOrder:=op_att;
|
instr.OpOrder:=op_att;
|
||||||
BuildOpcode(instr);
|
BuildOpcode(instr);
|
||||||
instr.AddReferenceSizes;
|
instr.AddReferenceSizes;
|
||||||
instr.SetInstructionOpsize;
|
instr.SetInstructionOpsize;
|
||||||
instr.CheckOperandSizes;
|
instr.CheckOperandSizes;
|
||||||
|
instr.FixupOpcode;
|
||||||
instr.ConcatInstruction(curlist);
|
instr.ConcatInstruction(curlist);
|
||||||
instr.Free;
|
instr.Free;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user