0

I'm trying to detect if the CPU is INTEL or not in linux using delphi by using this fucntion

    function IsIntelCPU: Boolean;
begin
{$IFDEF CPUINTEL}
  result := true;
{$ELSE}
  result := false;
{$ENDIF}
end;

but it doesn't work, if i issue "iscpu" command it will result

lscpu
Architecture:        x86_64
CPU op-mode(s):      32-bit, 64-bit
Byte Order:          Little Endian
CPU(s):              4
On-line CPU(s) list: 0-3
Thread(s) per core:  1
Core(s) per socket:  1
Socket(s):           4
NUMA node(s):        1
Vendor ID:           GenuineIntel
CPU family:          6
Model:               79
Model name:          Intel(R) Xeon(R) CPU E5-2696 v4 @ 2.20GHz
Stepping:            1
CPU MHz:             2199.996
BogoMIPS:            4399.99
Hypervisor vendor:   KVM
Virtualization type: full
L1d cache:           32K
L1i cache:           32K
L2 cache:            4096K
L3 cache:            16384K
NUMA node0 CPU(s):   0-3
Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single pti ssbd ibrs ibpb stibp fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt arat

is 100% intel cpu, can anyone help? thanks...

Int20h
  • 19
  • 4
  • 1
    Does [this](https://stackoverflow.com/questions/13874152/porting-assembler-x86-cpu-id-code-to-amd64) help? – Margaret Bloom Feb 27 '23 at 17:54
  • Hi margaret, in delphi for linux it doesnt support in line asm, : Unsupported language feature: 'ASM'. – Int20h Feb 27 '23 at 17:58
  • 3
    `CPUINTEL` is not defined by Embarcadero (see [Predefined Conditionals](https://docwiki.embarcadero.com/RADStudio/Sydney/en/Conditional_compilation_(Delphi)#Predefined_Conditionals)), the only CPU conditionals mentioned for Linux are `CPUX64` and `CPU64BITS`, which is why your code is not working. – Remy Lebeau Feb 27 '23 at 18:55
  • 2
    Hmm, you can of course just read `/proc/cpuinfo`. It’s fairly standard that `procfs(5)` is mounted, but on an embedded target I wouldn’t count on that. – Kai Burghardt Feb 27 '23 at 22:50
  • Actually, the question has not much sense. Currently Delphi for Linux only supports Intel x64 CPU. – fpiette Feb 28 '23 at 07:40
  • Are you sure you need to detect Intel CPUs separately from other x86-64 vendors like AMD, Via and Zhaoxin? (@fpiette: wait what? Delphi doesn't support current AMD Ryzen CPUs? Or are you calling those "Intel", because Intel designed the architecture that AMD extended to create AMD64, later x86-64 once Intel started making compatible 64-bit x86 CPUs?) – Peter Cordes Feb 28 '23 at 08:23
  • 2
    If you truly do need to detect *Intel*, you need to do that at run-time, because the same executable can run on CPUs from different x86 vendors. A good way is with the `cpuid` instruction, with EAX=0 so it produces `GenuinIntel` in EBX:EDX:ECX. Since you say inline asm doesn't work, write a whole function in asm and call it. Or if there's a `cpuid` wrapper, use it. – Peter Cordes Feb 28 '23 at 08:27
  • 1
    Are you trying to detect the CPU at run time? If so this code makes no sense because {$IFDEF...} only takes effect at compile time at which point you can only detect which processor you are compiling for. The title of the question would imply that that is what you are trying to do. – Dsm Feb 28 '23 at 08:48
  • A lot of helpful informations. thanks to all, I was trying to get INTEL random number generator. that's why i need to know the intel is present or not. :D – Int20h Mar 01 '23 at 08:32

1 Answers1

2

You cannot use Conditionals (IFDEF) like this. It's used to include or exclude code when compiling. See Predefined Conditionals

I'm unsure about other linux distros but Ubuntu has a /proc/cpuinfo file. You can load this into a string list or use your own method to parse it. There's a vendor_id and a model name field. This is not ideal but it will give you the information you seek and more!

EDIT: As per comment the file should exist on almost all linux distros.

I have tested the following on Ubuntu:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Classes;

function IsIntelCPU: Boolean;
const
  FILE_CPU_INFO = '/proc/cpuinfo';
begin
  var sl := TStringList.Create;
  try
    sl.LoadFromFile(FILE_CPU_INFO);

    for var aLine in sl do
    begin
      if aLine.Contains('vendor_id') and aLine.Contains('GenuineIntel') then
      begin
        Result := True;
        Break;
      end
      else
        Result := False;
    end;
  finally
    sl.Free;
  end;
end;

procedure Main;
begin
  if IsIntelCPU then
    Writeln('This is a Intel CPU System')
  else
    Writeln('This is NOT a Intel CPU System');
end;

begin
  try
    Main;
    ReadLn;
  except
    on E: Exception do
    begin
      Writeln(E.ClassName, ': ', E.Message);
      ReadLn;
    end;
  end;
end.
Adriaan
  • 806
  • 7
  • 24
  • Every mainstream Linux distro mounts the kernel's procfs filesystem on `/proc`, so `/proc/cpuinfo` will be there except in unusual system configurations (like very early boot, or if the user runs it in a chroot where they forgot to mount /proc). Lots of this depend on `/proc` so you can pretty much assume this if you can't easily get your program to run a `cpuid` instruction itself. – Peter Cordes Feb 28 '23 at 09:31