-3

I'm trying to port some code from old Delphi7 to Lazarus but following code just won't compile. Lazarus always complains about unknown identifiers.

function GetCPUID(Leaf, Subleaf: Integer): TCPUID;
begin
asm
{$IF Defined(CPUX86)}
  push  ebx
  push  edi
  mov   edi, ecx
  mov   ecx, edx
  cpuid
  mov   [edi+$0], eax
  mov   [edi+$4], ebx
  mov   [edi+$8], ecx
  mov   [edi+$c], edx
  pop   edi
  pop   ebx
{$ELSEIF Defined(CPUX64)}
  mov   r9,rcx
  mov   ecx,r8d
  mov   r8,rbx
  mov   eax,edx
  cpuid
  mov   [r9+$0], eax
  mov   [r9+$4], ebx
  mov   [r9+$8], ecx
  mov   [r9+$c], edx
  mov   rbx, r8
{$ELSE}
  {$Message Fatal 'GetCPUID has not been implemented for this architecture.'};
{$IFEND}
end;                 
ERROR MESSAGES
Compile Project, Target: C:\Users\Dave\AppData\Local\Temp\project1.exe: Exit code 1, Errors: 40, Warnings: 4
unit1.pas(65,9) Error: Unknown identifier "R9"
unit1.pas(65,12) Error: Unknown identifier "RCX"
unit1.pas(66,9) Error: Unknown identifier "ECX"
unit1.pas(66,13) Error: Unknown identifier "R8D"
unit1.pas(67,9) Error: Unknown identifier "R8"
unit1.pas(67,12) Error: Unknown identifier "RBX"
unit1.pas(68,9) Error: Unknown identifier "EAX"
unit1.pas(68,13) Error: Unknown identifier "EDX"
unit1.pas(70,9) Error: Assembler syntax error in operand
unit1.pas(70,10) Error: Unknown identifier "R9"
unit1.pas(70,14) Error: Dollar token is used without an identifier
unit1.pas(70,15) Error: Invalid constant expression
unit1.pas(70,16) Error: Invalid reference syntax
unit1.pas(70,18) Error: Unknown identifier "EAX"
unit1.pas(70,18) Error: No size specified and unable to determine the size of the operands
unit1.pas(70,18) Warning: Size suffix and destination or source size do not match
unit1.pas(71,9) Error: Assembler syntax error in operand
unit1.pas(71,10) Error: Unknown identifier "R9"
unit1.pas(71,14) Error: Dollar token is used without an identifier
unit1.pas(71,15) Error: Invalid constant expression
unit1.pas(71,16) Error: Invalid reference syntax
unit1.pas(71,18) Error: Unknown identifier "EBX"
unit1.pas(71,18) Error: No size specified and unable to determine the size of the operands
unit1.pas(71,18) Warning: Size suffix and destination or source size do not match
unit1.pas(72,9) Error: Assembler syntax error in operand
unit1.pas(72,10) Error: Unknown identifier "R9"
unit1.pas(72,14) Error: Dollar token is used without an identifier
unit1.pas(72,15) Error: Invalid constant expression
unit1.pas(72,16) Error: Invalid reference syntax
unit1.pas(72,18) Error: Unknown identifier "ECX"
unit1.pas(72,18) Error: No size specified and unable to determine the size of the operands
unit1.pas(72,18) Warning: Size suffix and destination or source size do not match
unit1.pas(73,9) Error: Assembler syntax error in operand
unit1.pas(73,10) Error: Unknown identifier "R9"
unit1.pas(73,15) Error: Unknown identifier "C"
unit1.pas(73,15) Error: Invalid constant expression
unit1.pas(73,16) Error: Invalid reference syntax
unit1.pas(73,18) Error: Unknown identifier "EDX"
unit1.pas(73,18) Error: No size specified and unable to determine the size of the operands
unit1.pas(73,18) Warning: Size suffix and destination or source size do not match
unit1.pas(74,9) Error: Unknown identifier "RBX"
unit1.pas(74,14) Error: Unknown identifier "R8"
unit1.pas(83,1) Error: Illegal expression
unit1.pas(83,11) Fatal: Syntax error, ";" expected but "identifier TFORM1" found
Luuk
  • 12,245
  • 5
  • 22
  • 33
Atak_Snajpera
  • 619
  • 9
  • 24
  • 2 questions: 1) what do you mean with "jsdkhfjksdhfjkhsdjkfhksdhkfhsdkjhfsdjkhfjksdhkfhsdkjfhjsdkhfkjsdhfjksdhjkfhsdkjfhjksdhfjksdhjfksdfksdhjkfhsdjkhfjksdhfkjhsdkhfdfgdfgdggdfdgdfgdfgdfgdfgdfgdfgd", 2) Did you read how to include Assembly here: [Lazarus Inline Assembler](https://wiki.freepascal.org/Lazarus_Inline_Assembler) ? – Luuk Nov 20 '21 at 11:09
  • I had to add some dummy text because stackoverflow wouldn't allow me to post! – Atak_Snajpera Nov 20 '21 at 11:16
  • OK. I have added {$ASMMODE intel} and it seems to be working fine. At least it compiles! – Atak_Snajpera Nov 20 '21 at 11:20
  • @luuk I can't see any statement about the letter case in the document. What did I miss? – David Heffernan Nov 20 '21 at 12:52
  • @Luuk The fact that you aren't a Lazarus developer doesn't make your statement any more or less true. – David Heffernan Nov 20 '21 at 18:07
  • @David Heffernan , I added some more explanation about {$asmmode intel} in my answer. It isn't needed if you enable delphi compat mode, and for the cases where it is needed, it must be after the $mode command, because the $mode directive sets options en-masse and would overwrite it – Marco van de Voort Nov 25 '21 at 09:50

1 Answers1

0

First, from the errors of the code that you show, it is clear this was not tested in Delphi 7, for the simple reason that Delphi 7 doesn't support 64-bit registers like R8 and R9

Moreover, for Delphi compatibility enable a Delphi compatibility mode, try adding

{$mode delphi}

if you want to use default Lazarus {$mode objfpc}, add

{$asmmode intel} 

after the mode command

after the program or interface keywords. In addition your IFDEF clauses (CPUX86 and x64) don't seem to match FPC's.

Btw, many CPU tests have been prepared in unit cpu:

{ returns true, if the processor supports the cpuid instruction }
function cpuid_support : boolean;

{ returns true, if floating point is done by an emulator }
function floating_point_emulation : boolean;

{ returns the contents of the cr0 register }
function cr0 : longint;

function InterlockedCompareExchange128Support : boolean;
function AESSupport : boolean;inline;
function AVXSupport: boolean;inline;
function AVX2Support: boolean;inline;
function AVX512FSupport: boolean;inline;    
function AVX512DQSupport: boolean;inline;    
function AVX512IFMASupport: boolean;inline;    
function AVX512PFSupport: boolean;inline;    
function AVX512ERSupport: boolean;inline;    
function AVX512CDSupport: boolean;inline;    
function AVX512BWSupport: boolean;inline;    
function AVX512VLSupport: boolean;inline;    
function SHASupport: boolean;inline;    
function FMASupport: boolean;inline;
function POPCNTSupport: boolean;inline;
function SSE41Support: boolean;inline;
function SSE42Support: boolean;inline;
function MOVBESupport: boolean;inline;
function F16CSupport: boolean;inline;
function RDRANDSupport: boolean;inline;
function RTMSupport: boolean;inline;
function BMI1Support: boolean;inline;
function BMI2Support: boolean;inline;

var
  is_sse3_cpu : boolean = false;

I suggest to use these as much as possible.

Marco van de Voort
  • 25,628
  • 5
  • 56
  • 89