PascalScript: update to origin git 14dcc5133d4b0b4750ec27f8d0e57204fd827666 (single/double on 64 bit)

git-svn-id: trunk@47380 -
This commit is contained in:
martin 2015-01-14 15:00:13 +00:00
parent 9a43c7ee8f
commit 07ac489e6c
3 changed files with 134 additions and 70 deletions

View File

@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<Package Version="4">
<Name Value="pascalscript"/>
@ -60,7 +60,7 @@ Carlo Kok
RemObjects Software
"/>
<Version Build="1"/>
<Files Count="43">
<Files Count="46">
<Item1>
<Filename Value="uPSRuntime.pas"/>
<UnitName Value="uPSRuntime"/>
@ -234,6 +234,18 @@ RemObjects Software
<Filename Value="x86.inc"/>
<Type Value="Include"/>
</Item43>
<Item44>
<Filename Value="uPSC_comobj.pas"/>
<UnitName Value="uPSC_comobj"/>
</Item44>
<Item45>
<Filename Value="uPSComponent_COM.pas"/>
<UnitName Value="uPSComponent_COM"/>
</Item45>
<Item46>
<Filename Value="uPSR_comobj.pas"/>
<UnitName Value="uPSR_comobj"/>
</Item46>
</Files>
<Type Value="RunAndDesignTime"/>
<RequiredPkgs Count="1">

View File

@ -13,7 +13,7 @@ uses
uPSComponent_DB, uPSComponent_Default, uPSComponent_Forms, uPSComponent_StdCtrls, uPSUtils,
uPSDebugger, uPSDisassembly, uPSPreProcessor, uPSR_buttons, uPSR_classes, uPSR_controls,
uPSR_dateutils, uPSR_DB, uPSR_dll, uPSR_extctrls, uPSR_forms, uPSR_graphics, uPSR_menus,
uPSR_std, LazarusPackageIntf;
uPSR_std, uPSC_comobj, uPSComponent_COM, uPSR_comobj, LazarusPackageIntf;
implementation

View File

@ -8,33 +8,46 @@ const
{$IFDEF MSWINDOWS}{$DEFINE WINDOWS}{$ENDIF}
{$IFDEF WINDOWS}
type
TRegisters = packed record
_RCX, // 0
_RDX, // 8
_R8, // 16
_R9: IPointer; // 24
_XMM1, // 32
_XMM2, // 40
_XMM3: Double; // 48
Stack: Pointer; // 56
Items: {$IFDEF FPC}PtrUInt{$ELSE}IntPtr{$ENDIF}; // 64
SingleBits: Integer; // 72
end;
procedure x64call(
Address: Pointer;
out _RAX: IPointer;
_RCX, _RDX, _R8, _R9: IPointer;
var _XMM0: Double;
_XMM1, _XMM2, _XMM3: Double;
aStack: Pointer; aItems: {$IFDEF FPC}PtrUInt{$ELSE}IntPtr{$ENDIF}); assembler; {$IFDEF FPC}nostackframe;{$ENDIF}
var Registers: TRegisters); assembler; {$IFDEF FPC}nostackframe;{$ENDIF}
asm
(* Registers:
RCX: Address
RDX: *_RAX
R8: _RCX
R9: _RDX
R8: _XMM0
R9: _REGISTERS
fpc inserts an 20h emty space
*)
{$IFDEF FPC}
//{$IFDEF FPC}
push rbp
mov rbp,rsp
{$ENDIF}
// call debugbreak
push rcx // address
push rdx // _rax
push r8 // _rcx
push r9 // _rdx
mov rcx, aItems
mov rdx, aStack
//{$ENDIF}
push rcx // address ;rbp -8
push rdx // @_rax ;rbp -16
push r8 // @_xmm0 ;rbp -24
push r9 // _registers ;rbp -32
mov rax, [rbp-32] //registers
mov rcx, [rax+64] // items/count
mov rdx, [rax+56] // stack
jmp @compareitems
@work:
{$IFDEF FPC}
@ -49,23 +62,55 @@ asm
jnz @work
// copy registers
{$IFDEF FPC}
movd xmm0,[_XMM0]
movd xmm1,_XMM1
movd xmm2,_XMM2
movd xmm3,_XMM3
{$ELSE}
mov rax, [_XMM0]
movsd xmm0, qword ptr [rax]
movsd xmm1,_XMM1
movsd xmm2,_XMM2
movsd xmm3,_XMM3
{$ENDIF}
mov rcx, [rax+72] // single bits
bt rcx, 1
jnc @g1
cvtsd2ss xmm1, [rax+32]
jmp @g1e
@g1:
movsd xmm1, [rax+32]
@g1e:
bt rcx, 2
jnc @g2
cvtsd2ss xmm2, [rax+40]
jmp @g2e
@g2:
movsd xmm2, [rax+40]
@g2e:
bt rcx, 3
jnc @g3
cvtsd2ss xmm3, [rax+40]
jmp @g3e
@g3:
movsd xmm3, [rax+40]
@g3e:
// rbp-16: address of xmm0
bt rcx, 0
jnc @g0
mov rdx, [rbp -24]
cvtsd2ss xmm0, [rdx]
jmp @g0e
@g0:
mov rdx, [rbp -24]
movsd xmm0, [rdx]
@g0e:
// other registers
mov rcx, [rax]
mov rdx, [rax+8]
mov r8, [rax+16]
mov r9, [rax+24]
mov RAX, [rbp-8]
mov RCX, [rbp-24]
mov RDX, [rbp-32]
mov R8, _R8
mov R9, _R9
// weird thing on windows, it needs 32 bytes in the CALLEE side to do whatever in
sub RSP, 32
@ -77,17 +122,19 @@ asm
// copy result back
mov RDX, [rbp-16]
mov [RDX], RAX
{$IFDEF FPC}
movd [_XMM0],xmm0
{$ELSE}
mov rax, [_XMM0]
movsd qword ptr [rax], xmm0
{$ENDIF}
pop r9
pop r8
pop rdx
pop rcx
mov rax, [rbp-32] //registers
bt [rax+72], 8
jnc @g5
cvtss2sd xmm1,xmm0
movd [rsi],xmm1
@g5:
mov RDX, [rbp-24]
movd [rdx],xmm0
@g5e:
leave
ret
end;
@ -278,12 +325,9 @@ function TPSExec.InnerfuseCall(_Self, Address: Pointer; CallingConv: TPSCallingC
var
Stack: array of Byte;
_RAX: IPointer;
{$IFDEF WINDOWS}
_RCX, _RDX, _R8, _R9: IPointer;
_XMM0, _XMM1, _XMM2, _XMM3: Double;
{$ELSE}
_XMM0: Double;
Registers: TRegisters;
{$IFNDEF WINDOWS}
RegUsageFloat: Byte;
{$ENDIF}
RegUsage: Byte;
@ -310,10 +354,10 @@ _XMM0: Double;
var p: Pointer;
begin
case RegUsage of
0: begin inc(RegUsage); _RCX:=Data; end;
1: begin inc(RegUsage); _RDX:=Data; end;
2: begin inc(RegUsage); _R8:=Data; end;
3: begin inc(RegUsage); _R9:=Data; end;
0: begin inc(RegUsage); Registers._RCX:=Data; end;
1: begin inc(RegUsage); Registers._RDX:=Data; end;
2: begin inc(RegUsage); Registers._R8:=Data; end;
3: begin inc(RegUsage); Registers._R9:=Data; end;
else begin
SetLength(Stack, Length(Stack)+8);
p := @Stack[LEngth(Stack)-8];
@ -360,9 +404,24 @@ _XMM0: Double;
begin
case RegUsage of
0: begin inc(RegUsage); _XMM0:=Data; end;
1: begin inc(RegUsage); _XMM1:=Data; end;
2: begin inc(RegUsage); _XMM2:=Data; end;
3: begin inc(RegUsage); _XMM3:=Data; end;
1: begin inc(RegUsage); Registers._XMM1:=Data; end;
2: begin inc(RegUsage); Registers._XMM2:=Data; end;
3: begin inc(RegUsage); Registers._XMM3:=Data; end;
else begin
SetLength(Stack, Length(Stack)+8);
p := @Stack[LEngth(Stack)-8];
Double(p^) := data;
end;
end;
end;
procedure StoreReg(data: Single); overload;
var p: Pointer;
begin
case RegUsage of
0: begin inc(RegUsage); Registers.SingleBits := Registers.SingleBits or 1;_XMM0:=Data; end;
1: begin inc(RegUsage); Registers.SingleBits := Registers.SingleBits or 2; Registers._XMM1:=Data; end;
2: begin inc(RegUsage); Registers.SingleBits := Registers.SingleBits or 4;Registers._XMM2:=Data; end;
3: begin inc(RegUsage); Registers.SingleBits := Registers.SingleBits or 8; Registers._XMM3:=Data; end;
else begin
SetLength(Stack, Length(Stack)+8);
p := @Stack[LEngth(Stack)-8];
@ -574,29 +633,18 @@ begin
_XMM5 := 0;
_XMM6 := 0;
_XMM7 := 0;*)
FillChar(Registers, Sizeof(REgisters), 0);
_XMM0 := 0;
RegUsageFloat := 0;
{$ELSE}
_RCX := 0;
_RDX := 0;
_R8 := 0;
_R9 := 0;
_XMM0 := 0;
_XMM1 := 0;
_XMM2 := 0;
_XMM3 := 0;
{$ENDIF}
_XMM0 := 0;
FillChar(Registers, Sizeof(REgisters), 0);
_RAX := 0;
RegUsage := 0;
if assigned(_Self) then begin
StoreReg(IPointer(_Self));
end;
{$IFNDEF WINDOWS}
if assigned(res) and (res^.atype.basetype = btSingle) then begin
Registers.Singlebits := Registers.Singlebits or 256;
end;
{$ENDIF}
{$IFDEF PS_RESBEFOREPARAMETERS}
if assigned(res) then begin
case res^.aType.BaseType of
@ -639,7 +687,9 @@ begin
{$ENDIF}
if Stack = nil then pp := nil else pp := @Stack[Length(Stack) -8];
{$IFDEF WINDOWS}
x64call(Address, _RAX, _RCX, _RDX, _R8, _R9, _XMM0, _XMM1, _XMM2, _XMM3, pp, Length(Stack) div 8);
Registers.Stack := pp;
Registers.Items := Length(Stack) div 8;
x64call(Address, _RAX, _XMM0, Registers);
{$ELSE}
x64call(Address, _RAX, Registers, pp, Length(Stack) div 8, _XMM0);
{$ENDIF}
@ -684,7 +734,9 @@ begin
{$ENDIF}
if Stack = nil then pp := nil else pp := @Stack[Length(Stack) -8];
{$IFDEF WINDOWS}
x64call(Address, _RAX, _RCX, _RDX, _R8, _R9, _XMM0, _XMM1, _XMM2, _XMM3, pp, Length(Stack) div 8);
Registers.Stack := pp;
Registers.Items := Length(Stack) div 8;
x64call(Address, _RAX, _XMM0, Registers);
{$ELSE}
x64call(Address, _RAX, Registers, pp, Length(Stack) div 8, _XMM0);
{$ENDIF}