mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 15:49:27 +02:00
* fixed a bug which caused non commutative fpu instructions to be wrong when using an intel-style external assembler and compiling a smartlinked unit
git-svn-id: branches/i8086@24151 -
This commit is contained in:
parent
74cd67b85c
commit
c3aaa37c0c
@ -306,7 +306,14 @@ interface
|
||||
procedure changeopsize(siz:topsize);
|
||||
|
||||
function GetString:string;
|
||||
procedure CheckNonCommutativeOpcodes;
|
||||
|
||||
{ This is a workaround for the GAS non commutative fpu instruction braindamage.
|
||||
Early versions of the UnixWare assembler had a bug where some fpu instructions
|
||||
were reversed and GAS still keeps this "feature" for compatibility.
|
||||
for details: http://sourceware.org/binutils/docs/as/i386_002dBugs.html#i386_002dBugs
|
||||
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=372528
|
||||
http://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax#Caveats }
|
||||
function FixNonCommutativeOpcodes: tasmop;
|
||||
private
|
||||
FOperandOrder : TOperandOrder;
|
||||
procedure init(_size : topsize); { this need to be called by all constructor }
|
||||
@ -961,8 +968,10 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure taicpu.CheckNonCommutativeOpcodes;
|
||||
function taicpu.FixNonCommutativeOpcodes: tasmop;
|
||||
begin
|
||||
result:=opcode;
|
||||
|
||||
{ we need ATT order }
|
||||
SetOperandOrder(op_att);
|
||||
|
||||
@ -981,21 +990,21 @@ implementation
|
||||
(ops=0) then
|
||||
begin
|
||||
if opcode=A_FSUBR then
|
||||
opcode:=A_FSUB
|
||||
result:=A_FSUB
|
||||
else if opcode=A_FSUB then
|
||||
opcode:=A_FSUBR
|
||||
result:=A_FSUBR
|
||||
else if opcode=A_FDIVR then
|
||||
opcode:=A_FDIV
|
||||
result:=A_FDIV
|
||||
else if opcode=A_FDIV then
|
||||
opcode:=A_FDIVR
|
||||
result:=A_FDIVR
|
||||
else if opcode=A_FSUBRP then
|
||||
opcode:=A_FSUBP
|
||||
result:=A_FSUBP
|
||||
else if opcode=A_FSUBP then
|
||||
opcode:=A_FSUBRP
|
||||
result:=A_FSUBRP
|
||||
else if opcode=A_FDIVRP then
|
||||
opcode:=A_FDIVP
|
||||
result:=A_FDIVP
|
||||
else if opcode=A_FDIVP then
|
||||
opcode:=A_FDIVRP;
|
||||
result:=A_FDIVRP;
|
||||
end;
|
||||
if (
|
||||
(ops=1) and
|
||||
@ -1005,13 +1014,13 @@ implementation
|
||||
) then
|
||||
begin
|
||||
if opcode=A_FSUBRP then
|
||||
opcode:=A_FSUBP
|
||||
result:=A_FSUBP
|
||||
else if opcode=A_FSUBP then
|
||||
opcode:=A_FSUBRP
|
||||
result:=A_FSUBRP
|
||||
else if opcode=A_FDIVRP then
|
||||
opcode:=A_FDIVP
|
||||
result:=A_FDIVP
|
||||
else if opcode=A_FDIVP then
|
||||
opcode:=A_FDIVRP;
|
||||
result:=A_FDIVRP;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -537,6 +537,7 @@ interface
|
||||
{$ifdef cpuextended}
|
||||
e : extended;
|
||||
{$endif cpuextended}
|
||||
fixed_opcode: TAsmOp;
|
||||
begin
|
||||
if not assigned(p) then
|
||||
exit;
|
||||
@ -884,12 +885,12 @@ interface
|
||||
|
||||
ait_instruction :
|
||||
begin
|
||||
taicpu(hp).CheckNonCommutativeOpcodes;
|
||||
fixed_opcode:=taicpu(hp).FixNonCommutativeOpcodes;
|
||||
{ We need intel order, no At&t }
|
||||
taicpu(hp).SetOperandOrder(op_intel);
|
||||
s:='';
|
||||
if ((taicpu(hp).opcode=A_FADDP) or
|
||||
(taicpu(hp).opcode=A_FMULP))
|
||||
if ((fixed_opcode=A_FADDP) or
|
||||
(fixed_opcode=A_FMULP))
|
||||
and (taicpu(hp).ops=0) then
|
||||
begin
|
||||
taicpu(hp).allocate_oper(2);
|
||||
@ -898,7 +899,7 @@ interface
|
||||
taicpu(hp).oper[1]^.typ:=top_reg;
|
||||
taicpu(hp).oper[1]^.reg:=NR_ST;
|
||||
end;
|
||||
if taicpu(hp).opcode=A_FWAIT then
|
||||
if fixed_opcode=A_FWAIT then
|
||||
AsmWriteln(#9#9'DB'#9'09bh')
|
||||
else
|
||||
begin
|
||||
@ -906,18 +907,18 @@ interface
|
||||
word prefix to get selectors
|
||||
to be pushed in 2 bytes PM }
|
||||
if (taicpu(hp).opsize=S_W) and
|
||||
((taicpu(hp).opcode=A_PUSH) or
|
||||
(taicpu(hp).opcode=A_POP)) and
|
||||
((fixed_opcode=A_PUSH) or
|
||||
(fixed_opcode=A_POP)) and
|
||||
(taicpu(hp).oper[0]^.typ=top_reg) and
|
||||
(is_segment_reg(taicpu(hp).oper[0]^.reg)) then
|
||||
AsmWriteln(#9#9'DB'#9'066h');
|
||||
AsmWrite(#9#9+std_op2str[taicpu(hp).opcode]+cond2str[taicpu(hp).condition]);
|
||||
AsmWrite(#9#9+std_op2str[fixed_opcode]+cond2str[taicpu(hp).condition]);
|
||||
if taicpu(hp).ops<>0 then
|
||||
begin
|
||||
if is_calljmp(taicpu(hp).opcode) then
|
||||
if is_calljmp(fixed_opcode) then
|
||||
begin
|
||||
AsmWrite(#9);
|
||||
WriteOper_jmp(taicpu(hp).oper[0]^,taicpu(hp).opcode);
|
||||
WriteOper_jmp(taicpu(hp).oper[0]^,fixed_opcode);
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -927,7 +928,7 @@ interface
|
||||
AsmWrite(#9)
|
||||
else
|
||||
AsmWrite(',');
|
||||
WriteOper(taicpu(hp).oper[i]^,taicpu(hp).opsize,taicpu(hp).opcode,taicpu(hp).ops,(i=2));
|
||||
WriteOper(taicpu(hp).oper[i]^,taicpu(hp).opsize,fixed_opcode,taicpu(hp).ops,(i=2));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user