mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-23 00:09:31 +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 CheckNonCommutativeOpcodes;
|
||||
procedure SwapOperands;
|
||||
{ Additional actions required by specific reader }
|
||||
procedure FixupOpcode;virtual;
|
||||
{ opcode adding }
|
||||
function ConcatInstruction(p : TAsmList) : tai;override;
|
||||
end;
|
||||
@ -535,6 +537,11 @@ begin
|
||||
opcode:=A_FDIVRP;
|
||||
end;
|
||||
|
||||
procedure Tx86Instruction.FixupOpcode;
|
||||
begin
|
||||
{ does nothing by default }
|
||||
end;
|
||||
|
||||
{*****************************************************************************
|
||||
opcode Adding
|
||||
*****************************************************************************}
|
||||
@ -623,18 +630,6 @@ begin
|
||||
siz:=S_FAR;
|
||||
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
|
||||
for version 2.9.1 and 2.10
|
||||
we add explicit args to it !! }
|
||||
|
@ -42,6 +42,9 @@ Interface
|
||||
procedure MaybeGetPICModifier(var oper: tx86operand);
|
||||
end;
|
||||
|
||||
Tx86attInstruction = class(Tx86Instruction)
|
||||
procedure FixupOpcode;override;
|
||||
end;
|
||||
|
||||
Implementation
|
||||
|
||||
@ -63,6 +66,37 @@ Implementation
|
||||
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;
|
||||
var
|
||||
len : longint;
|
||||
@ -848,12 +882,13 @@ Implementation
|
||||
var
|
||||
instr : Tx86Instruction;
|
||||
begin
|
||||
instr:=Tx86Instruction.Create(Tx86Operand);
|
||||
instr:=Tx86attInstruction.Create(Tx86Operand);
|
||||
instr.OpOrder:=op_att;
|
||||
BuildOpcode(instr);
|
||||
instr.AddReferenceSizes;
|
||||
instr.SetInstructionOpsize;
|
||||
instr.CheckOperandSizes;
|
||||
instr.FixupOpcode;
|
||||
instr.ConcatInstruction(curlist);
|
||||
instr.Free;
|
||||
end;
|
||||
|
@ -43,12 +43,13 @@ Unit rax64att;
|
||||
var
|
||||
instr : Tx86Instruction;
|
||||
begin
|
||||
instr:=Tx86Instruction.Create(Tx86Operand);
|
||||
instr:=Tx86attInstruction.Create(Tx86Operand);
|
||||
instr.OpOrder:=op_att;
|
||||
BuildOpcode(instr);
|
||||
instr.AddReferenceSizes;
|
||||
instr.SetInstructionOpsize;
|
||||
instr.CheckOperandSizes;
|
||||
instr.FixupOpcode;
|
||||
instr.ConcatInstruction(curlist);
|
||||
instr.Free;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user