* Fixed handling of 'movq' instruction by assembler reader, resolves #18205.

git-svn-id: trunk@17497 -
This commit is contained in:
sergei 2011-05-19 06:44:24 +00:00
parent e271595e20
commit 08e895cf7c
3 changed files with 45 additions and 14 deletions

View File

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

View File

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

View File

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