[fpc-pascal] Converting 32bit intel asm to Pascal or 64bit at&t asm
Andrew Haines
AndrewD207 at aol.com
Wed Mar 9 17:58:08 CET 2011
On 03/08/11 19:58, Andrew Haines wrote:
> Hi,
>
> I'm trying to convert the following 32bit asm to pascal so it's
> portable. Also to 64bit asm.
>
> It's from ACS audio component suite.
>
> What am I doing wrong?
>
For anyone who's interested I fixed the 64bit assembly version which is
good enough for me but I had hoped to write pascal code for the function.
I converted the intel32 asm to att32 asm which showed my first problem
"FDIVP" on intel becomes "FDIVRP" but on att it stays the same which
causes a different result. Beyond that, there wern't many problems. I
had some fun wondering why the RCX register wasn't a reasonable value
until I realized I was copying 64bits from a 32bit variable.
The following is my result. The 32bit and 64bit asm work but the pascal
still does not. Any suggestions are welcome.
procedure LgMagnitude(InData : PACSComplex; OutData : PDouble;
DataSize, Shift : Integer);
{$IFDEF CPUI386}
var
LogBase : Double;
begin
asm
FLD1;
FLDL2T;
FDIVrP;
FSTPQ LogBase;
MOVL DataSize, %ecx;
MOVL OutData, %edi;
MOVL InData, %esi;
.Ltest: DEC %ecx
JZ .Lout;
FLDQ (%esi);
FMULQ %ST(0), %ST(0);
ADDL $8, %esi;
FLDQ (%esi);
FMULQ %ST(0), %ST(0);
FADDP;
FSQRTQ;
FTSTQ;
FSTSW %AX;
SAHF;
JE .Lskip;
FLDQ LogBase;
FXCH;
FYL2X;
FIADDL Shift;
FTSTQ;
FSTSW %AX;
SAHF;
JAE .Lskip;
FSTPQ (%edi);
FLDZ;
.Lskip:
ADDL $8, %esi;
FSTPQ (%edi);
ADDL $8, %edi;
JMP .Ltest;
.Lout: ;
end;
end;
{$ELSE} {$IFDEF CPUX86_64}
var
LogBase : Double;
begin
SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide,
exOverflow, exUnderflow, exPrecision]);
asm
FLD1;
FLDL2T;
FDIVrP;
FSTPQ LogBase;
MOV DataSize, %ecx;
MOV OutData, %rdi;
MOV InData, %rsi;
.Ltest: DEC %ecx
JZ .Lout;
FLDL (%rsi);
FMUL %ST(0), %ST(0);
ADD $8, %rsi;
FLDL (%rsi);
FMUL %ST(0), %ST(0);
FADDP;
FSQRT;
FTST;
FSTSW %AX;
// SAHF is not available on all x86_64 processors so
this is the workaround
bt $14, %ax; // // copy fpu C3 flag to cpu
carry flag
JC .Lskip;
FLD LogBase;
FXCH;
FYL2X;
FIADDL Shift;
FTST;
FSTSW %AX;
// SAHF is not available on all x86_64 processors so
this is the workaround
bt $8, %ax // copy fpu C0 flag to cpu carry flag
JNC .Lskip
FSTPL (%rdi);
FLDZ;
.Lskip:
ADDL $8, %rsi;
FSTPL (%rdi);
ADDL $8, %rdi;
JMP .Ltest;
.Lout: ;
end;
end;
{$ELSE}
{$ERROR LgMagnitude Unimplemented}
// the following is not correct but was my best effort at pascalizing
the asm code
var
LogBase : Double;
i: Integer;
Im, Re: Double;
Tmp: Double;
begin
asm
FLD1;
FLDL2T;
FDIVRP;
FSTP LogBase;
end;
for i := 0 to DataSize-1 do
begin
Im := InData[i].Im*InData[i].Im;
Re := InData[i].Re*InData[i].Re;
Tmp := sqr(Im+Re);
if Tmp <> Im then
begin
//Tmp := ln(Tmp)*LogBase+Shift; // same as the following asm proc?
asm
FLD LogBase;
FLD Tmp;
FYL2X;
FIADD Shift;
FSTP Tmp;
end;
if Tmp <> 0.0 then
begin
if 0.0 >= Tmp then
begin
Tmp := 0;
end;
end;
end;
OutData[i] := Tmp;
end;
end;
{$ENDIF CPUX86_64}
{$ENDIF CPUI386}
More information about the fpc-pascal
mailing list