I currently have the following code to support 10-bytes Extended values saved in binary files from Win32, and loading these in other platforms. However, for Android (which is ARM and not INTEL), I need some code to do conversion to and from 10-bytes IEEE format in 10-byte memory and the "Extended" type in the compiler (which is really an 8-byte Double).
TYPE
TExtended = TExtended80Rec;
{$IFDEF INTEL64 }
PROCEDURE ExtendedToIEEE(VAR D : Extended ; VAR E : TExtended); ASSEMBLER;
ASM
FLD QWORD PTR [RCX]
FSTP TBYTE PTR [RDX]
FWAIT
END;
PROCEDURE IEEEToExtended(CONST E : TExtended ; VAR D : Extended); ASSEMBLER;
ASM
FLD TBYTE PTR [RCX]
FSTP QWORD PTR [RDX]
FWAIT
END;
{$ELSE }
PROCEDURE ExtendedToIEEE(D : Extended ; VAR E : TExtended);
BEGIN
{$IF SizeOf(Extended)=SizeOf(TExtended) }
MOVE(D,E,SizeOf(Extended))
{$ELSE }
!! MISSING !!
{$ENDIF }
END;
PROCEDURE IEEEToExtended(CONST E : TExtended ; VAR D : Extended);
BEGIN
{$IF SizeOf(Extended)=SizeOf(TExtended) }
MOVE(E,D,SizeOf(Extended))
{$ELSE }
!! MISSING !!
{$ENDIF }
END;
{$ENDIF }
If possible, I'd also like to be able to convert to/from 16-bytes "Extended" type from MacOS/Linux (unless the 16-byte size is "just" an alignment, ie. 10-byte padded to 16).
With the help of David above in the comments, I have come up with this, and provide it here for future reference:
TYPE
TExtended = TExtended80Rec;
PExtended = ^TExtended;
{$IF SizeOf(Extended)=SizeOf(TExtended) }
PROCEDURE ExtendedToIntel(VAR D : Extended ; VAR E : TExtended); INLINE;
BEGIN
D:=Extended(E)
END;
PROCEDURE IntelToExtended(VAR E : TExtended ; VAR D : Extended); INLINE;
BEGIN
E:=TExtended(D)
END;
{$ELSEIF DEFINED(WIN64) }
PROCEDURE ExtendedToIntel(VAR D : Extended {Double} ; VAR E : TExtended); ASSEMBLER;
ASM
FLD QWORD PTR [RCX]
FSTP TBYTE PTR [RDX]
FWAIT
END;
PROCEDURE IntelToExtended(VAR E : TExtended ; VAR D : Extended {Double} ); ASSEMBLER;
ASM
FLD TBYTE PTR [RCX]
FSTP QWORD PTR [RDX]
FWAIT
END;
{$ELSE }
PROCEDURE ExtendedToIntel(D : Extended ; VAR E : TExtended);
BEGIN
PExtended(@E)^:=TExtended(D)
END;
PROCEDURE IntelToExtended(CONST E : TExtended ; VAR D : Extended);
BEGIN
D:=Double(PExtended(@E)^)
END;
{$ENDIF }
TYPE
TStreamHelper = CLASS HELPER FOR TStream
FUNCTION ReadExtended : Extended;
PROCEDURE WriteExtended(E : Extended);
END;
{$IF SizeOf(Extended)=SizeOf(TExtended) }
FUNCTION TStreamHelper.ReadExtended : Extended;
BEGIN
Read(Result,SizeOf(Extended))
END;
PROCEDURE TStreamHelper.WriteExtended(E : Extended);
BEGIN
Write(E,SizeOf(Extended))
END;
{$ELSE }
FUNCTION TStreamHelper.ReadExtended : Extended;
VAR
EX : TExtended;
BEGIN
Read(EX,SizeOf(TExtended));
IntelToExtended(EX,Result)
END;
PROCEDURE TStreamHelper.WriteExtended(E : Extended);
VAR
EX : TExtended;
BEGIN
ExtendedToIntel(E,EX);
Write(EX,SizeOf(EX))
END;
{$ENDIF }