mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 11:59:20 +02:00
added i386 extended conversions for powerpc
git-svn-id: trunk@5823 -
This commit is contained in:
parent
f0d075ab77
commit
1f1fe2413e
@ -478,8 +478,8 @@ end;
|
|||||||
procedure RaiseGDBException(const Msg: string);
|
procedure RaiseGDBException(const Msg: string);
|
||||||
|
|
||||||
Raises an exception.
|
Raises an exception.
|
||||||
gdb does not catch fpc Exception objects, therefore this procedure raises
|
gdb does normally not catch fpc Exception objects, therefore this procedure
|
||||||
a standard AV which is catched by gdb.
|
raises a standard AV which is catched by gdb.
|
||||||
------------------------------------------------------------------------------}
|
------------------------------------------------------------------------------}
|
||||||
procedure RaiseGDBException(const Msg: string);
|
procedure RaiseGDBException(const Msg: string);
|
||||||
begin
|
begin
|
||||||
@ -490,6 +490,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure MoveRectToFit(var ARect: TRect; const MaxRect: TRect);
|
procedure MoveRectToFit(var ARect: TRect; const MaxRect: TRect);
|
||||||
|
// move ARect, so it fits into MaxRect
|
||||||
|
// if MaxRect is too small, ARect is resized.
|
||||||
begin
|
begin
|
||||||
if ARect.Left<MaxRect.Left then begin
|
if ARect.Left<MaxRect.Left then begin
|
||||||
// move rectangle right
|
// move rectangle right
|
||||||
|
@ -170,7 +170,7 @@ type
|
|||||||
{$endif HASWIDESTRING}
|
{$endif HASWIDESTRING}
|
||||||
end;
|
end;
|
||||||
TLRSObjectWriterClass = class of TLRSObjectWriter;
|
TLRSObjectWriterClass = class of TLRSObjectWriter;
|
||||||
|
|
||||||
var
|
var
|
||||||
LazarusResources: TLResourceList;
|
LazarusResources: TLResourceList;
|
||||||
|
|
||||||
@ -209,6 +209,9 @@ procedure FormDataToText(FormStream, TextStream: TStream);
|
|||||||
|
|
||||||
procedure ReverseBytes(p: Pointer; Count: integer);
|
procedure ReverseBytes(p: Pointer; Count: integer);
|
||||||
procedure ReverseByteOrderInWords(p: PWord; Count: integer);
|
procedure ReverseByteOrderInWords(p: PWord; Count: integer);
|
||||||
|
function ConvertLRSExtendedToDouble(p: Pointer): Double;
|
||||||
|
procedure ConvertEndianBigDoubleToLRSExtended(BigEndianDouble,
|
||||||
|
LRSExtended: Pointer);
|
||||||
|
|
||||||
function ReadLRSWord(s: TStream): word;
|
function ReadLRSWord(s: TStream): word;
|
||||||
function ReadLRSInteger(s: TStream): integer;
|
function ReadLRSInteger(s: TStream): integer;
|
||||||
@ -223,6 +226,7 @@ function ReadLRSCurrency(s: TStream): Currency;
|
|||||||
{$ifdef HASWIDESTRING}
|
{$ifdef HASWIDESTRING}
|
||||||
function ReadLRSWideString(s: TStream): WideString;
|
function ReadLRSWideString(s: TStream): WideString;
|
||||||
{$endif HASWIDESTRING}
|
{$endif HASWIDESTRING}
|
||||||
|
function ReadLRSEndianLittleExtendedAsDouble(s: TStream): Double;
|
||||||
|
|
||||||
procedure WriteLRSWord(s: TStream; const w: word);
|
procedure WriteLRSWord(s: TStream; const w: word);
|
||||||
procedure WriteLRSInteger(s: TStream; const i: integer);
|
procedure WriteLRSInteger(s: TStream; const i: integer);
|
||||||
@ -244,7 +248,7 @@ procedure WriteLRS8BytesReversed(s: TStream; p: Pointer);
|
|||||||
procedure WriteLRS10BytesReversed(s: TStream; p: Pointer);
|
procedure WriteLRS10BytesReversed(s: TStream; p: Pointer);
|
||||||
procedure WriteLRSNull(s: TStream; Count: integer);
|
procedure WriteLRSNull(s: TStream; Count: integer);
|
||||||
procedure WriteLRSEndianBigDoubleAsEndianLittleExtended(s: TStream;
|
procedure WriteLRSEndianBigDoubleAsEndianLittleExtended(s: TStream;
|
||||||
PPCDouble: PByte);
|
EndBigDouble: PByte);
|
||||||
procedure WriteLRSReversedWords(s: TStream; p: Pointer; Count: integer);
|
procedure WriteLRSReversedWords(s: TStream; p: Pointer; Count: integer);
|
||||||
|
|
||||||
|
|
||||||
@ -1788,35 +1792,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure ReverseBytes(p: Pointer; Count: integer);
|
|
||||||
var
|
|
||||||
p1: PChar;
|
|
||||||
p2: PChar;
|
|
||||||
c: Char;
|
|
||||||
begin
|
|
||||||
p1:=PChar(p);
|
|
||||||
p2:=PChar(p)+Count-1;
|
|
||||||
while p1<p2 do begin
|
|
||||||
c:=p1^;
|
|
||||||
p1^:=p2^;
|
|
||||||
p2^:=c;
|
|
||||||
inc(p1);
|
|
||||||
dec(p2);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure ReverseByteOrderInWords(p: PWord; Count: integer);
|
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
w: Word;
|
|
||||||
begin
|
|
||||||
for i:=0 to Count-1 do begin
|
|
||||||
w:=p[i];
|
|
||||||
w:=(w shr 8) or ((w and $ff) shl 8);
|
|
||||||
p[i]:=w;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function InitLazResourceComponent(Instance: TComponent;
|
function InitLazResourceComponent(Instance: TComponent;
|
||||||
RootAncestor: TClass): Boolean;
|
RootAncestor: TClass): Boolean;
|
||||||
|
|
||||||
@ -1892,6 +1867,116 @@ begin
|
|||||||
Result:=TWriter.Create(Driver);
|
Result:=TWriter.Create(Driver);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ LRS format converter functions }
|
||||||
|
|
||||||
|
procedure ReverseBytes(p: Pointer; Count: integer);
|
||||||
|
var
|
||||||
|
p1: PChar;
|
||||||
|
p2: PChar;
|
||||||
|
c: Char;
|
||||||
|
begin
|
||||||
|
p1:=PChar(p);
|
||||||
|
p2:=PChar(p)+Count-1;
|
||||||
|
while p1<p2 do begin
|
||||||
|
c:=p1^;
|
||||||
|
p1^:=p2^;
|
||||||
|
p2^:=c;
|
||||||
|
inc(p1);
|
||||||
|
dec(p2);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure ReverseByteOrderInWords(p: PWord; Count: integer);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
w: Word;
|
||||||
|
begin
|
||||||
|
for i:=0 to Count-1 do begin
|
||||||
|
w:=p[i];
|
||||||
|
w:=(w shr 8) or ((w and $ff) shl 8);
|
||||||
|
p[i]:=w;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ConvertLRSExtendedToDouble(p: Pointer): Double;
|
||||||
|
type
|
||||||
|
Ti386ExtendedReversed = packed record
|
||||||
|
{$IFDEF Endian_BIG}
|
||||||
|
ExponentAndSign: word;
|
||||||
|
Mantissa: qword;
|
||||||
|
{$ELSE}
|
||||||
|
Mantissa: qword;
|
||||||
|
ExponentAndSign: word;
|
||||||
|
{$ENDIF}
|
||||||
|
end;
|
||||||
|
var
|
||||||
|
e: Ti386ExtendedReversed;
|
||||||
|
Exponent: word;
|
||||||
|
ExponentAndSign: word;
|
||||||
|
Mantissa: qword;
|
||||||
|
begin
|
||||||
|
System.Move(p^,e,10);
|
||||||
|
{$IFDEF Endian_BIG}
|
||||||
|
ReverseBytes(@e,10);
|
||||||
|
{$ENDIF}
|
||||||
|
// i386 extended
|
||||||
|
Exponent:=(e.ExponentAndSign and $7fff);
|
||||||
|
if (Exponent>$4000+$3ff) or (Exponent<$4000-$400) then begin
|
||||||
|
// exponent out of bounds
|
||||||
|
Result:=0;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
dec(Exponent,$4000-$400);
|
||||||
|
ExponentAndSign:=Exponent or ((e.ExponentAndSign and $8000) shr 4);
|
||||||
|
// i386 extended has leading 1, double has not (shl 1)
|
||||||
|
// i386 has 64 bit, double has 52 bit (shr 12)
|
||||||
|
Mantissa:=(e.Mantissa shl 1) shr 12;
|
||||||
|
// put together
|
||||||
|
QWord(Result):=Mantissa or (qword(ExponentAndSign) shl 52);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure ConvertEndianBigDoubleToLRSExtended(BigEndianDouble,
|
||||||
|
LRSExtended: Pointer);
|
||||||
|
// Floats consists of a sign bit, some exponent bits and the mantissa bits
|
||||||
|
// A 0 is all bits 0
|
||||||
|
// not 0 has always a leading 1, which exponent is stored
|
||||||
|
// Single/Double does not save the leading 1, Extended does.
|
||||||
|
//
|
||||||
|
// Double is 8 bytes long, leftmost bit is sign,
|
||||||
|
// then 11 bit exponent based $400, then 52 bit mantissa without leading 1
|
||||||
|
//
|
||||||
|
// Extended is 10 bytes long, leftmost bit is sign,
|
||||||
|
// then 15 bit exponent based $4000, then 64 bit mantissa with leading 1
|
||||||
|
// EndianLittle means reversed byte order
|
||||||
|
var
|
||||||
|
e: array[0..9] of byte;
|
||||||
|
i: Integer;
|
||||||
|
Exponent: Word;
|
||||||
|
d: PByte;
|
||||||
|
begin
|
||||||
|
d:=PByte(BigEndianDouble);
|
||||||
|
// convert ppc double to i386 extended
|
||||||
|
if (PCardinal(d)[0] or PCardinal(d)[1])=0 then begin
|
||||||
|
// 0
|
||||||
|
FillChar(LRSExtended^,10,#0);
|
||||||
|
end else begin
|
||||||
|
Exponent:=((d[0] and $7f) shl 4)+(d[1] shr 4);
|
||||||
|
inc(Exponent,$4000-$400);
|
||||||
|
if (d[0] and $80)>0 then
|
||||||
|
// signed
|
||||||
|
inc(Exponent,$8000);
|
||||||
|
e[9]:=Exponent shr 8;
|
||||||
|
e[8]:=Exponent and $ff;
|
||||||
|
e[7]:=($80 or (d[1] shl 3) or (d[2] shr 5)) and $ff;
|
||||||
|
for i:=3 to 7 do begin
|
||||||
|
e[9-i]:=((d[i-1] shl 3) or (d[i] shr 5)) and $ff;
|
||||||
|
end;
|
||||||
|
e[1]:=(d[7] shl 3) and $ff;
|
||||||
|
e[0]:=0;
|
||||||
|
System.Move(e[0],LRSExtended^,10);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function ReadLRSWord(s: TStream): word;
|
function ReadLRSWord(s: TStream): word;
|
||||||
begin
|
begin
|
||||||
s.Read(Result,2);
|
s.Read(Result,2);
|
||||||
@ -1940,24 +2025,13 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$IFDEF CPUPowerPC}
|
|
||||||
function ReadLRSExtentedAndConvertToExtended(s: TStream): Extended;
|
|
||||||
// TODO
|
|
||||||
begin
|
|
||||||
s.Read(Result,4);
|
|
||||||
s.Read(Result,4);
|
|
||||||
s.Read(Result,2);
|
|
||||||
Result:=0;
|
|
||||||
end;
|
|
||||||
{$ENDIF}
|
|
||||||
|
|
||||||
function ReadLRSExtended(s: TStream): Extended;
|
function ReadLRSExtended(s: TStream): Extended;
|
||||||
begin
|
begin
|
||||||
{$IFDEF CPUi386}
|
{$IFDEF CPUi386}
|
||||||
s.Read(Result,10);
|
s.Read(Result,10);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
{$IFDEF CPUPowerPC}
|
{$IFDEF CPUPowerPC}
|
||||||
Result:=ReadLRSExtentedAndConvertToExtended(s);
|
Result:=ReadLRSEndianLittleExtendedAsDouble(s);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1987,6 +2061,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
{$endif HASWIDESTRING}
|
{$endif HASWIDESTRING}
|
||||||
|
|
||||||
|
function ReadLRSEndianLittleExtendedAsDouble(s: TStream): Double;
|
||||||
|
var
|
||||||
|
e: array[1..10] of byte;
|
||||||
|
begin
|
||||||
|
s.Read(e,10);
|
||||||
|
Result:=ConvertLRSExtendedToDouble(@e);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure WriteLRSReversedWord(s: TStream; w: word);
|
procedure WriteLRSReversedWord(s: TStream; w: word);
|
||||||
begin
|
begin
|
||||||
w:=(w shr 8) or ((w and $ff) shl 8);
|
w:=(w shr 8) or ((w and $ff) shl 8);
|
||||||
@ -2046,15 +2128,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure WriteLRSEndianBigDoubleAsEndianLittleExtended(s: TStream;
|
procedure WriteLRSEndianBigDoubleAsEndianLittleExtended(s: TStream;
|
||||||
PPCDouble: PByte);
|
EndBigDouble: PByte);
|
||||||
// TODO
|
|
||||||
var
|
var
|
||||||
i: Integer;
|
e: array[0..9] of byte;
|
||||||
begin
|
begin
|
||||||
i:=0;
|
ConvertEndianBigDoubleToLRSExtended(EndBigDouble,@e);
|
||||||
s.Write(i,4);
|
s.Write(e[0],10);
|
||||||
s.Write(i,4);
|
|
||||||
s.Write(i,2);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure WriteLRSWord(s: TStream; const w: word);
|
procedure WriteLRSWord(s: TStream; const w: word);
|
||||||
@ -2294,19 +2373,21 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TLRSObjectReader.ReadFloat: Extended;
|
function TLRSObjectReader.ReadFloat: Extended;
|
||||||
|
{$ifdef Endian_BIG}
|
||||||
|
var
|
||||||
|
e: array[1..10] of byte;
|
||||||
|
{$endif}
|
||||||
begin
|
begin
|
||||||
{$ifdef CPUPowerPC}
|
|
||||||
debugln('WARNING: TLRSObjectReader.ReadFloat not yet implemented for powerpc');
|
|
||||||
Read(Result, 4);
|
|
||||||
Read(Result, 4);
|
|
||||||
Read(Result, 2);
|
|
||||||
Result:=0;
|
|
||||||
exit;
|
|
||||||
{$endif CPUPowerPC}
|
|
||||||
|
|
||||||
Read(Result, 10);
|
|
||||||
{$ifdef Endian_BIG}
|
{$ifdef Endian_BIG}
|
||||||
ReverseBytes(@Result,10);
|
if SizeOf(extended)=10 then begin
|
||||||
|
Read(Result, 10);
|
||||||
|
ReverseBytes(@Result,10);
|
||||||
|
end else begin
|
||||||
|
Read(e,10);
|
||||||
|
Result:=ConvertLRSExtendedToDouble(@e);
|
||||||
|
end;
|
||||||
|
{$else not Endian_BIG}
|
||||||
|
Read(Result, 10);
|
||||||
{$endif}
|
{$endif}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2640,14 +2721,19 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLRSObjectWriter.WriteExtendedContent(e: Extended);
|
procedure TLRSObjectWriter.WriteExtendedContent(e: Extended);
|
||||||
|
{$IFDEF Endian_BIG}
|
||||||
|
var
|
||||||
|
LRSExtended: array[1..10] of byte;
|
||||||
|
{$endif}
|
||||||
begin
|
begin
|
||||||
{$IFDEF Endian_BIG}
|
{$IFDEF Endian_BIG}
|
||||||
{$IFDEF CPUPowerPC}
|
if SizeOf(e)=10 then begin
|
||||||
debugln('WARNING: TLRSObjectWriter.WriteExtendedContent not yet implemented for powerpc');
|
ReverseBytes(@e,10);
|
||||||
WriteNulls(10);
|
Write(e,10);
|
||||||
exit;
|
end else begin
|
||||||
{$ENDIF}
|
ConvertEndianBigDoubleToLRSExtended(@e,@LRSExtended);
|
||||||
ReverseBytes(@e,10);
|
Write(LRSExtended,10);
|
||||||
|
end;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Write(e,10);
|
Write(e,10);
|
||||||
end;
|
end;
|
||||||
@ -2705,7 +2791,8 @@ end;
|
|||||||
destructor TLRSObjectWriter.Destroy;
|
destructor TLRSObjectWriter.Destroy;
|
||||||
begin
|
begin
|
||||||
// Flush all data which hasn't been written yet
|
// Flush all data which hasn't been written yet
|
||||||
FlushBuffer;
|
if Assigned(FStream) then
|
||||||
|
FlushBuffer;
|
||||||
|
|
||||||
if Assigned(FBuffer) then
|
if Assigned(FBuffer) then
|
||||||
FreeMem(FBuffer, FBufSize);
|
FreeMem(FBuffer, FBufSize);
|
||||||
|
Loading…
Reference in New Issue
Block a user