Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Index: x64.inc
- ===================================================================
- --- x64.inc (revision 38441)
- +++ x64.inc (working copy)
- @@ -14,7 +14,7 @@
- _RCX, _RDX, _R8, _R9: IPointer;
- var _XMM0: Double;
- _XMM1, _XMM2, _XMM3: Double;
- - aStack: Pointer; aItems: IntPtr); assembler; {$IFDEF FPC}nostackframe;{$ENDIF}
- + aStack: Pointer; aItems: PtrUInt); assembler; {$IFDEF FPC}nostackframe;{$ENDIF}
- asm
- (* Registers:
- RCX: Address
- @@ -37,7 +37,7 @@
- mov rdx, aStack
- jmp @compareitems
- @work:
- - push [rdx]
- + push qword ptr [rdx]
- dec rcx
- sub rdx,8
- @compareitems:
- @@ -280,6 +280,9 @@
- CallData: TPSList;
- I: Integer;
- pp: ^Byte;
- +{$IFDEF FPC}
- + IsVirtualCons: Boolean;
- +{$ENDIF}
- function rp(p: PPSVariantIFC): PPSVariantIFC;
- begin
- @@ -535,8 +538,10 @@
- begin
- GetMem(p, PointerSize2);
- TMethod(p^) := MKMethod(Self, Longint(FVar.Dta^));
- - StoreStack(p^, Pointersize2);
- - FreeMem(p);
- + //StoreStack(p^, Pointersize2);
- + StoreReg(IPointer(p));
- + //_RAX:=IPointer(TMethod(p^).Code);
- + //FreeMem(p);
- end;
- bts64:
- @@ -579,8 +584,21 @@
- {$ENDIF}
- _RAX := 0;
- RegUsage := 0;
- + {$IFDEF FPC}
- + // FIX FOR FPC constructor calls
- + if (Integer(CallingConv) and 128) <> 0 then begin
- + IsVirtualCons := true;
- + end else
- + IsVirtualCons:= false;
- + if IsVirtualCons then begin
- + if not GetPtr(rp(Params[0])) then exit; // this goes first
- + StoreReg(IPointer(_Self));
- + Params.Delete(0);
- + end else
- + {$ENDIF}
- if assigned(_Self) then begin
- StoreReg(IPointer(_Self));
- + //_RAX := IPointer(_Self);
- end;
- {$IFNDEF WINDOWS}
- if assigned(res) and (res^.atype.basetype = btSingle) then begin
- Index: uPSRuntime.pas
- ===================================================================
- --- uPSRuntime.pas (revision 38441)
- +++ uPSRuntime.pas (working copy)
- @@ -11462,8 +11462,10 @@
- {$ENDIF}
- {$ifdef fpc}
- - {$if defined(cpupowerpc) or defined(cpuarm) or defined(cpu64)}
- + {$if defined(cpupowerpc) or defined(cpuarm)}
- {$define empty_methods_handler}
- + {$elseif defined(cpu64)}
- + {$define fpc_64_methods_handler}
- {$ifend}
- {$endif}
- @@ -11473,9 +11475,352 @@
- end;
- {$else}
- +{$ifdef fpc_64_methods_handler}
- +function SupportsRegister(b: TPSTypeRec): Boolean;
- +begin
- + case b.BaseType of
- + btU8,
- + bts8,
- + bts16,
- + btu16,
- + bts32,
- + btu32,
- + btstring,
- + btclass,
- +{$IFNDEF PS_NOINTERFACES}
- + btinterface,
- +{$ENDIF}
- + btPChar,
- +{$IFNDEF PS_NOWIDESTRING}
- + btwidestring,
- + btUnicodeString,
- + btWideChar,
- +{$ENDIF}
- + btChar,
- + btArray,
- + btSingle,
- + btDouble,
- + btEnum: Result := true;
- + btSet: Result := b.RealSize <= PointerSize;
- + btStaticArray: Result := b.RealSize <= PointerSize;
- + else
- + Result := false;
- + end;
- +end;
- +function ResultAsRegister(b: TPSTypeRec): Boolean;
- +begin
- + case b.BaseType of
- + btSingle,
- + btDouble,
- + // btExtended, <-- What about that??
- + btU8,
- + bts8,
- + bts16,
- + btu16,
- + bts32,
- + btu32,
- +{$IFDEF PS_FPCSTRINGWORKAROUND}
- + btString,
- +{$ENDIF}
- +{$IFNDEF PS_NOINT64}
- + bts64,
- +{$ENDIF}
- + btPChar,
- +{$IFNDEF PS_NOWIDESTRING}
- + btWideChar,
- +{$ENDIF}
- + btChar,
- + btclass,
- + btEnum: Result := true;
- + btSet: Result := b.RealSize <= PointerSize;
- + btStaticArray: Result := b.RealSize <= PointerSize;
- + else
- + Result := false;
- + end;
- +end;
- +
- +function AlwaysAsVariable(aType: TPSTypeRec): Boolean;
- +begin
- + case atype.BaseType of
- + btVariant: Result := true;
- + btSet: Result := atype.RealSize > PointerSize;
- + btRecord: Result := atype.RealSize > PointerSize;
- + btStaticArray: Result := atype.RealSize > PointerSize;
- + else
- + Result := false;
- + end;
- +end;
- +
- +function MyAllMethodsHandler2_64(Self: PScriptMethodInfo; const StackAndParams: Pointer): Integer;
- +type
- + __PARAM_RECORD = packed record
- + _xmm3_a, _xmm3_b: Pointer;
- + _xmm2_a, _xmm2_b: Pointer;
- + _xmm1_a, _xmm1_b: Pointer;
- + _xmm0_a, _xmm0_b: Pointer;
- + R9, R8, RDX, RCX, RAX: Pointer;
- + Rest: array [0..0] of Pointer;
- + end;
- + PPARAM_RECORD = ^__PARAM_RECORD;
- +
- +var
- + Decl: tbtString;
- + I, C, regno: Integer;
- + Params: TPSList;
- + Res, Tmp: PIFVariant;
- + cpt: PIFTypeRec;
- + fmod: tbtchar;
- + s,e: tbtString;
- + FStack: pointer;
- + ex: TPSExceptionHandler;
- + paramRecord:PPARAM_RECORD;
- +begin
- + //Get Declaration, i.e. Types & Number of Parameters
- + Decl := TPSInternalProcRec(Self^.Se.FProcs[Self^.ProcNo]).ExportDecl;
- +
- + paramRecord:=StackAndParams;
- + FStack := @paramRecord^.Rest;
- + Params := TPSList.Create;
- + s := decl;
- + grfw(s);
- + //Add spare parameters
- + while s <> '' do
- + begin
- + Params.Add(nil);
- + grfw(s);
- + end;
- + c := Params.Count;
- + regno := 0;
- + Result := 0;
- + s := decl;
- + grfw(s);
- +
- + //Fill parameters
- + for i := c-1 downto 0 do
- + begin
- + //Get parameter Type and Param-Object
- + e := grfw(s);
- + fmod := e[1];
- + delete(e, 1, 1);
- + //Type of Parameter
- + cpt := Self.Se.GetTypeNo(StrToInt(e));
- + //--Pointers etc.
- + if ((fmod = '%') or (fmod = '!') or (AlwaysAsVariable(cpt))) and (RegNo < 4) then
- + begin
- + tmp := CreateHeapVariant(self.Se.FindType2(btPointer));
- + PPSVariantPointer(tmp).DestType := cpt;
- + Params[i] := tmp;
- + case regno of
- + 0: begin
- + PPSVariantPointer(tmp).DataDest := paramRecord^.RCX;
- + inc(regno);
- + end;
- + 1: begin
- + PPSVariantPointer(tmp).DataDest := paramRecord^.RDX;
- + inc(regno);
- + end;
- + 2: begin
- + PPSVariantPointer(tmp).DataDest := paramRecord^.R8;
- + inc(regno);
- + end;
- + 3: begin
- + PPSVariantPointer(tmp).DataDest := paramRecord^.R9;
- + inc(regno);
- + end;
- + end;
- + end
- + //--all types of parameters that can be stored in registers
- + else if SupportsRegister(cpt) and (RegNo < 4) then
- + begin
- + tmp := CreateHeapVariant(cpt);
- + Params[i] := tmp;
- + case regno of
- + 0: begin
- + if (cpt.BaseType=btSingle) or (cpt.BaseType=btDouble) then
- + CopyArrayContents(@PPSVariantData(tmp)^.Data, @paramRecord^._xmm0_a, 1, cpt)
- + else
- + CopyArrayContents(@PPSVariantData(tmp)^.Data, @paramRecord^.RCX, 1, cpt);
- + inc(regno);
- + end;
- + 1: begin
- + if (cpt.BaseType=btSingle) or (cpt.BaseType=btDouble) then
- + CopyArrayContents(@PPSVariantData(tmp)^.Data, @paramRecord^._xmm1_a, 1, cpt)
- + else
- + CopyArrayContents(@PPSVariantData(tmp)^.Data, @paramRecord^.RDX, 1, cpt);
- + inc(regno);
- + end;
- + 2: begin
- + if (cpt.BaseType=btSingle) or (cpt.BaseType=btDouble) then
- + CopyArrayContents(@PPSVariantData(tmp)^.Data, @paramRecord^._xmm2_a, 1, cpt)
- + else
- + CopyArrayContents(@PPSVariantData(tmp)^.Data, @paramRecord^.R8, 1, cpt);
- + inc(regno);
- + end;
- + 3: begin
- + if (cpt.BaseType=btSingle) or (cpt.BaseType=btDouble) then
- + CopyArrayContents(@PPSVariantData(tmp)^.Data, @paramRecord^._xmm3_a, 1, cpt)
- + else
- + CopyArrayContents(@PPSVariantData(tmp)^.Data, @paramRecord^.R9, 1, cpt) ;
- + inc(regno);
- + end;
- + end;
- + end;
- + end;
- + //Start over for Returnvalue
- + s := decl;
- + e := grfw(s);
- + if e <> '-1' then
- + begin
- + cpt := Self.Se.GetTypeNo(StrToInt(e));
- + if not ResultAsRegister(cpt) then
- + begin
- + Res := CreateHeapVariant(Self.Se.FindType2(btPointer));
- + PPSVariantPointer(Res).DestType := cpt;
- + Params.Add(Res);
- + PPSVariantPointer(Res).DataDest := @paramRecord^.RAX;
- + end{ else //Are there return values on the Stack in x64 - probably yes, but how?
- + begin
- + Res := CreateHeapVariant(cpt);
- + Params.Add(Res);
- + end};
- + end else Res := nil;
- +
- + //Now push remaining parameters on the Stack
- + s := decl;
- + grfw(s);
- + for i := 0 to c -1 do
- + begin
- + //Get type
- + e := grlw(s);
- + fmod := e[1];
- + delete(e, 1, 1);
- + //Already in a register?
- + if Params[i] <> nil then Continue;
- + cpt := Self.Se.GetTypeNo(StrToInt(e));
- + //Pointer?
- + if (fmod = '%') or (fmod = '!') or (AlwaysAsVariable(cpt)) then
- + begin
- + tmp := CreateHeapVariant(self.Se.FindType2(btPointer));
- + PPSVariantPointer(tmp).DestType := cpt;
- + Params[i] := tmp;
- + PPSVariantPointer(tmp).DataDest := Pointer(FStack^);
- + FStack := Pointer(IPointer(FStack) + PointerSize);
- + Inc(Result, PointerSize);
- + end
- +(* else if SupportsRegister(cpt) then
- + begin
- + tmp := CreateHeapVariant(cpt);
- + Params[i] := tmp;
- + CopyArrayContents(@PPSVariantData(tmp)^.Data, Pointer(FStack), 1, cpt);
- + FStack := Pointer(IPointer(FStack) + 4);
- + end;
- + end *)else
- + begin
- + tmp := CreateHeapVariant(cpt);
- + Params[i] := tmp;
- + CopyArrayContents(@PPSVariantData(tmp)^.Data, Pointer(FStack), 1, cpt);
- + FStack := Pointer((IPointer(FStack) + cpt.RealSize + 3) and not 3);
- + Inc(Result, (cpt.RealSize + 3) and not 3);
- + end;
- + end;
- +
- + //Create exception handler and call the beast!
- + ex := TPSExceptionHandler.Create;
- + ex.FinallyOffset := InvalidVal;
- + ex.ExceptOffset := InvalidVal;
- + ex.Finally2Offset := InvalidVal;
- + ex.EndOfBlock := InvalidVal;
- + ex.CurrProc := nil;
- + ex.BasePtr := Self.Se.FCurrStackBase;
- + Ex.StackSize := Self.Se.FStack.Count;
- + i := Self.Se.FExceptionStack.Add(ex);
- + Self.Se.RunProc(Params, Self.ProcNo);
- + if Self.Se.FExceptionStack[i] = ex then
- + begin
- + Self.Se.FExceptionStack.Remove(ex);
- + ex.Free;
- + end;
- +
- + //Anything to return?
- + if (Res <> nil) then
- + begin
- + Params.DeleteLast;
- + if (ResultAsRegister(Res.FType)) then
- + begin
- + CopyArrayContents(@paramRecord^.RAX, @PPSVariantData(res)^.Data, 1, Res^.FType);
- + end;
- + DestroyHeapVariant(res);
- + end;
- +
- + //Free allocated data
- + for i := 0 to Params.Count -1 do
- + DestroyHeapVariant(Params[i]);
- + Params.Free;
- +
- + //Any exceptions?
- + if Self.Se.ExEx <> erNoError then
- + begin
- + if Self.Se.ExObject <> nil then
- + begin
- + FStack := Self.Se.ExObject;
- + Self.Se.ExObject := nil;
- + raise TObject(FStack);
- + end else
- + raise EPSException.Create(PSErrorToString(Self.SE.ExceptionCode, Self.Se.ExceptionString), Self.Se, Self.Se.ExProc, Self.Se.ExPos);
- + end;
- +end;
- +
- +procedure MyAllMethodsHandler;
- +asm
- + push rbp
- + mov rbp,rsp
- + push rax // for eventual result values...
- + push rcx // SELF
- + push rdx // PARAM 1 (bossibly)
- + push r8 // PARAM 2
- + push r9 // PARAM 3
- + sub rsp, 16
- + movdqu [rsp], xmm0
- + sub rsp, 16
- + movdqu [rsp], xmm1
- + sub rsp, 16
- + movdqu [rsp], xmm2
- + sub rsp, 16
- + movdqu [rsp], xmm3
- +
- + mov rdx, rsp
- +
- + sub RSP, 32 //Create Savehouse for storing registers...
- +
- + call MyAllMethodsHandler2_64
- +
- + add RSP, 32
- +
- + movdqu xmm3, [rsp]
- + add rsp, 16
- + movdqu xmm2, [rsp]
- + add rsp, 16
- + movdqu xmm1, [rsp]
- + add rsp, 16
- + movdqu xmm0, [rsp]
- + add rsp, 16
- + pop r9
- + pop r8
- + pop rdx
- + pop rcx
- + pop rax
- +
- + leave
- +
- + add rsp, 8 //cleanup stackframe generated by FPC
- + ret
- +end;
- +{$else}
- +
- function MyAllMethodsHandler2(Self: PScriptMethodInfo; const Stack: PPointer; _EDX, _ECX: Pointer): Integer; forward;
- +
- procedure MyAllMethodsHandler;
- // On entry:
- // EAX = Self pointer
- @@ -11781,7 +12126,9 @@
- raise EPSException.Create(PSErrorToString(Self.SE.ExceptionCode, Self.Se.ExceptionString), Self.Se, Self.Se.ExProc, Self.Se.ExPos);
- end;
- end;
- -{$endif}
- +{$endif} //fpc_64_method_handler
- +{$endif} //empty_method_handler
- +
- function TPSRuntimeClassImporter.FindClass(const Name: tbtString): TPSRuntimeClass;
- var
- h, i: Longint;
Advertisement
Add Comment
Please, Sign In to add comment