cpuwin.inc 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2006 by Florian Klaempfl and Pavel Ozerski
  4. member of the Free Pascal development team.
  5. FPC Pascal system unit x86-64 specific part for the Win64 API.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$asmmode att}
  13. function StackTop: pointer; assembler;nostackframe;
  14. asm
  15. movq %gs:(8),%rax
  16. end;
  17. {$ifdef FPC_USE_WIN64_SEH}
  18. function main_wrapper(arg: Pointer; proc: Pointer): ptrint; assembler; nostackframe;
  19. asm
  20. subq $40, %rsp
  21. .seh_stackalloc 40
  22. .seh_endprologue
  23. call %rdx { "arg" is passed in %rcx }
  24. nop { this nop is critical for exception handling }
  25. addq $40, %rsp
  26. .seh_handler __FPC_default_handler,@except,@unwind
  27. end;
  28. {$endif FPC_USE_WIN64_SEH}
  29. var
  30. { old compilers emitted a reference to _fltused if a module contains
  31. floating type code so the linker could leave away floating point
  32. libraries or not. VC does this as well so we need to define this
  33. symbol as well (FK)
  34. }
  35. _fltused : int64;cvar;public;
  36. { value of the stack segment
  37. to check if the call stack can be written on exceptions }
  38. _SS : Cardinal;
  39. {$ifdef VER3_0}
  40. procedure Exe_entry;[public,alias:'_FPC_EXE_Entry'];
  41. {$else VER3_0}
  42. procedure Exe_entry(constref info: TEntryInformation);[public,alias:'_FPC_EXE_Entry'];
  43. {$endif VER3_0}
  44. begin
  45. {$ifndef VER3_0}
  46. SetupEntryInformation(info);
  47. {$endif VER3_0}
  48. IsLibrary:=false;
  49. { install the handlers for exe only ?
  50. or should we install them for DLL also ? (PM) }
  51. {$ifndef SYSTEM_USE_WIN_SEH}
  52. install_exception_handlers;
  53. {$endif SYSTEM_USE_WIN_SEH}
  54. ExitCode:=0;
  55. asm
  56. xorq %rax,%rax
  57. movw %ss,%ax
  58. movl %eax,_SS(%rip)
  59. movq %rbp,%rsi
  60. xorq %rbp,%rbp
  61. {$ifdef VER3_0}
  62. {$ifdef FPC_USE_WIN64_SEH}
  63. xor %rcx,%rcx
  64. lea PASCALMAIN(%rip),%rdx
  65. call main_wrapper
  66. {$else FPC_USE_WIN64_SEH}
  67. call PASCALMAIN
  68. {$endif FPC_USE_WIN64_SEH}
  69. {$else VER3_0}
  70. {$ifdef FPC_USE_WIN64_SEH}
  71. xor %rcx,%rcx
  72. lea EntryInformation(%rip),%rdx
  73. movq TEntryInformation.PascalMain(%rdx),%rdx
  74. call main_wrapper
  75. {$else FPC_USE_WIN64_SEH}
  76. lea EntryInformation(%rip),%rdx
  77. call TEntryInformation.PascalMain(%rdx)
  78. {$endif FPC_USE_WIN64_SEH}
  79. {$endif VER3_0}
  80. movq %rsi,%rbp
  81. end ['RSI','RBP']; { <-- specifying RSI allows compiler to save/restore it properly }
  82. { if we pass here there was no error ! }
  83. system_exit;
  84. end;
  85. function is_prefetch(p : pointer) : boolean;
  86. var
  87. a : array[0..15] of byte;
  88. doagain : boolean;
  89. instrlo,instrhi,opcode : byte;
  90. i : longint;
  91. begin
  92. result:=false;
  93. { read memory savely without causing another exeception }
  94. if not(ReadProcessMemory(GetCurrentProcess,p,@a,sizeof(a),nil)) then
  95. exit;
  96. i:=0;
  97. doagain:=true;
  98. while doagain and (i<15) do
  99. begin
  100. opcode:=a[i];
  101. instrlo:=opcode and $f;
  102. instrhi:=opcode and $f0;
  103. case instrhi of
  104. { prefix? }
  105. $20,$30:
  106. doagain:=(instrlo and 7)=6;
  107. $60:
  108. doagain:=(instrlo and $c)=4;
  109. $f0:
  110. doagain:=instrlo in [0,2,3];
  111. $0:
  112. begin
  113. result:=(instrlo=$f) and (a[i+1] in [$d,$18]);
  114. exit;
  115. end;
  116. else
  117. doagain:=false;
  118. end;
  119. inc(i);
  120. end;
  121. end;