cpu.pp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Florian Klaempfl
  4. This unit contains some routines to get informations about the
  5. processor
  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. {$mode objfpc}
  13. unit cpu;
  14. interface
  15. { returns true, if the processor supports the cpuid instruction }
  16. function cpuid_support : boolean;
  17. { returns true, if floating point is done by an emulator }
  18. function floating_point_emulation : boolean;
  19. { returns the contents of the cr0 register }
  20. function cr0 : longint;
  21. function AVXSupport: boolean;inline;
  22. function AVX2Support: boolean;inline;
  23. function FMASupport: boolean;inline;
  24. var
  25. is_sse3_cpu : boolean = false;
  26. implementation
  27. {$ASMMODE INTEL}
  28. var
  29. _AVXSupport,
  30. _AVX2Support,
  31. _FMASupport : boolean;
  32. function cpuid_support : boolean;assembler;
  33. {
  34. Check if the ID-flag can be changed, if changed then CpuID is supported.
  35. Tested under go32v1 and Linux on c6x86 with CpuID enabled and disabled (PFV)
  36. }
  37. asm
  38. push ebx
  39. pushfd
  40. pushfd
  41. pop eax
  42. mov ebx,eax
  43. xor eax,200000h
  44. push eax
  45. popfd
  46. pushfd
  47. pop eax
  48. popfd
  49. and eax,200000h
  50. and ebx,200000h
  51. cmp eax,ebx
  52. setnz al
  53. pop ebx
  54. end;
  55. function cr0 : longint;assembler;
  56. asm
  57. DB 0Fh,20h,0C0h
  58. { mov eax,cr0
  59. special registers are not allowed in the assembler
  60. parsers }
  61. end;
  62. function floating_point_emulation : boolean;
  63. begin
  64. {!!!! I don't know currently the position of the EM flag }
  65. { $4 after Ralf Brown's list }
  66. floating_point_emulation:=(cr0 and $4)<>0;
  67. end;
  68. {$ASMMODE ATT}
  69. function XGETBV(i : dword) : int64;assembler;
  70. asm
  71. movl %eax,%ecx
  72. // older FPCs don't know the xgetbv opcode
  73. .byte 0x0f,0x01,0xd0
  74. end;
  75. procedure SetupSupport;
  76. var
  77. _ecx,_ebx : longint;
  78. begin
  79. is_sse3_cpu:=false;
  80. if cpuid_support then
  81. begin
  82. asm
  83. pushl %ebx
  84. movl $1,%eax
  85. cpuid
  86. movl %ecx,_ecx
  87. popl %ebx
  88. end;
  89. is_sse3_cpu:=(_ecx and $1)<>0;
  90. _AVXSupport:=
  91. { XGETBV suspport? }
  92. ((_ecx and $08000000)<>0) and
  93. { xmm and ymm state enabled? }
  94. ((XGETBV(0) and %110)=%110) and
  95. { avx supported? }
  96. ((_ecx and $10000000)<>0);
  97. _FMASupport:=_AVXSupport and ((_ecx and $1000)<>0);
  98. asm
  99. pushl %ebx
  100. movl $7,%eax
  101. movl $0,%ecx
  102. cpuid
  103. movl %ebx,_ebx
  104. popl %ebx
  105. end;
  106. _AVX2Support:=_AVXSupport and ((_ebx and $20)<>0);
  107. end;
  108. end;
  109. function AVXSupport: boolean;inline;
  110. begin
  111. result:=_AVXSupport;
  112. end;
  113. function AVX2Support: boolean;inline;
  114. begin
  115. result:=_AVX2Support;
  116. end;
  117. function FMASupport: boolean;inline;
  118. begin
  119. result:=_FMASupport;
  120. end;
  121. begin
  122. SetupSupport;
  123. end.