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? I tested my Pascal code with linux 32bit but the output differs from the 32bit asm. In 64bit linux it differs further but this could be from the ACS indicator component. I attached screenshots of the various configurations. I am using fpc 2.5.1 for 32bit and 64bit. Regards, Andrew TACSComplex = record Im, Re: Double; end; <original code> procedure LgMagnitude(InData : PACSComplex; OutData : PDouble; DataSize, Shift : Integer); var LogBase : Double; begin asm FLD1; FLDL2T; FDIVP; FSTP LogBase; MOV EDX, DataSize; SHL EDX, 3; MOV ECX, OutData; ADD EDX, ECX; MOV EAX, InData; @test: CMP EDX, ECX; JE @out; FLD QWORD[EAX]; FMUL ST(0), ST(0); ADD EAX, 8; FLD QWORD[EAX]; FMUL ST(0), ST(0); FADDP; FSQRT; FTST; PUSH EAX; FSTSW AX; SAHF; JE @skip; FLD LogBase; FXCH; FYL2X; FIADD Shift; FTST; FSTSW AX; SAHF; JAE @skip; FSTP QWORD[ECX]; FLDZ; @skip: POP EAX; ADD EAX, 8; FSTP QWORD[ECX]; ADD ECX, 8; JMP @test; @out: ; end; end; end; </original code> <pascal code> var LogBase : Double; i: Integer; Im, Re: Double; Tmp: Double; begin asm FLD1; FLDL2T; FDIVP; 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 := log2(Tmp)*LogBase+Shift; // is this the same as the following asm code? 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; end; </pascal code> <64bit asm> SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]); asm FLD1; FLDL2T; FDIVP; FSTP LogBase; MOV DataSize, %RDX; SHL $3, %RDX; MOV OutData, %RCX; ADD %RCX, %RDX; MOV InData, %RAX; MOV Shift, %rsi; .Ltest: CMP %RCX, %RDX; JE .Lout; FLD (%RAX); //FLD QWORD[%EAX]; FMUL %st(0), %st(0); ADD $8, %RAX; FLD (%RAX);//FLD QWORD[EAX]; // sigsegv here with fpu exceptions off. only happens after many iterations but seems immediate in real time. FMUL %st(0), %st(0); FADDP; FSQRT; FTST; PUSH %RAX; FSTSW %AX; //with fpu exceptions enabled I get a FPU exception here after some iterations but again it is immediate in realtime. //SAHF; // not available in amd64! //JE .Lskip; bt $14, %ax; // // copy fpu C3 flag to cpu carry flag JC .Lskip; FLD LogBase; FXCH; FYL2X; FIADD Shift; FTST; FSTSW %AX; //SAHF; // not available in amd64! //JAE .Lskip; bt $8, %ax // copy fpu C0 flag to cpu carry flag JNC .Lskip FSTP (%RCX);//FSTP QWORD[ECX]; FLDZ; .Lskip: POP %RAX; ADD $8, %RAX; FSTP (%RCX);//FSTP QWORD[RCX]; ADD $8, %RCX; JMP .Ltest; .Lout: ; end; end; </64bit asm>
<<attachment: 32bit-orig-asm.png>>
<<attachment: 32bit-pascal.png>>
<<attachment: 64bit-pascal.png>>
_______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal