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} _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal