cpuwin.inc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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. procedure Exe_entry(constref info: TEntryInformation);[public,alias:'_FPC_EXE_Entry'];
  40. begin
  41. SetupEntryInformation(info);
  42. IsLibrary:=false;
  43. { install the handlers for exe only ?
  44. or should we install them for DLL also ? (PM) }
  45. {$ifndef SYSTEM_USE_WIN_SEH}
  46. install_exception_handlers;
  47. {$endif SYSTEM_USE_WIN_SEH}
  48. ExitCode:=0;
  49. asm
  50. xorq %rax,%rax
  51. movw %ss,%ax
  52. movl %eax,_SS(%rip)
  53. movq %rbp,%rsi
  54. xorq %rbp,%rbp
  55. {$ifdef FPC_USE_WIN64_SEH}
  56. xor %rcx,%rcx
  57. lea EntryInformation(%rip),%rdx
  58. movq TEntryInformation.PascalMain(%rdx),%rdx
  59. call main_wrapper
  60. {$else FPC_USE_WIN64_SEH}
  61. lea EntryInformation(%rip),%rdx
  62. call TEntryInformation.PascalMain(%rdx)
  63. {$endif FPC_USE_WIN64_SEH}
  64. movq %rsi,%rbp
  65. end ['RSI','RBP']; { <-- specifying RSI allows compiler to save/restore it properly }
  66. { if we pass here there was no error ! }
  67. system_exit;
  68. end;
  69. function is_prefetch(p : pointer) : boolean;
  70. var
  71. a : array[0..15] of byte;
  72. doagain : boolean;
  73. instrlo,instrhi,opcode : byte;
  74. i : longint;
  75. begin
  76. result:=false;
  77. { read memory savely without causing another exeception }
  78. if not(ReadProcessMemory(GetCurrentProcess,p,@a,sizeof(a),nil)) then
  79. exit;
  80. i:=0;
  81. doagain:=true;
  82. while doagain and (i<15) do
  83. begin
  84. opcode:=a[i];
  85. instrlo:=opcode and $f;
  86. instrhi:=opcode and $f0;
  87. case instrhi of
  88. { prefix? }
  89. $20,$30:
  90. doagain:=(instrlo and 7)=6;
  91. $60:
  92. doagain:=(instrlo and $c)=4;
  93. $f0:
  94. doagain:=instrlo in [0,2,3];
  95. $0:
  96. begin
  97. result:=(instrlo=$f) and (a[i+1] in [$d,$18]);
  98. exit;
  99. end;
  100. else
  101. doagain:=false;
  102. end;
  103. inc(i);
  104. end;
  105. end;