How to check a computer if it supports SSE2 in Delphi 32?

C ++ way to do it here (under Windows).

same answer , but on Linux using GCC.

The output of the corresponding asm code, as I understand it:

mov eax, 1 cpuid mov features, edx 

I'm not very comfortable at BASM.

My question is:

I need to wrap a test as follows

 function IsSSE2: Boolean; begin try Result := False; // // Some BASM code here // except Result := False; end; end; 

Please help me.

+6
source share
3 answers

You can do this without assembler. Only works with Windows XP and newer.

 function IsProcessorFeaturePresent(ProcessorFeature: DWORD): BOOL; stdcall; external kernel32 name 'IsProcessorFeaturePresent'; const PF_XMMI64_INSTRUCTIONS_AVAILABLE = 10; function HasSSE2: boolean; begin result := IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE); end; 
+21
source

I think this does:

 function SupportsSSE2: LongBool; const CPUID_INTEL_SSE2 = $04000000; asm push ebx mov eax, 1 cpuid mov eax, FALSE test edx, CPUID_INTEL_SSE2 jz @END mov eax, TRUE @END: pop ebx end; 
+8
source

Here is the code used by the graphics32 library to detect processor functions:

 {$IFDEF WIN64} {$DEFINE TARGET_x64} {$ENDIF} type TCPUInstructionSet = (ciMMX, ciEMMX, ciSSE, ciSSE2, ci3DNow, ci3DNowExt); const CPUISChecks: Array[TCPUInstructionSet] of Cardinal = ($800000, $400000, $2000000, $4000000, $80000000, $40000000); {ciMMX , ciEMMX, ciSSE , ciSSE2 , ci3DNow , ci3DNowExt} function CPUID_Available: Boolean; asm {$IFDEF TARGET_x64} MOV EDX,False PUSHFQ POP RAX MOV ECX,EAX XOR EAX,$00200000 PUSH RAX POPFQ PUSHFQ POP RAX XOR ECX,EAX JZ @1 MOV EDX,True @1: PUSH RAX POPFQ MOV EAX,EDX {$ELSE} MOV EDX,False PUSHFD POP EAX MOV ECX,EAX XOR EAX,$00200000 PUSH EAX POPFD PUSHFD POP EAX XOR ECX,EAX JZ @1 MOV EDX,True @1: PUSH EAX POPFD MOV EAX,EDX {$ENDIF} end; function CPU_Signature: Integer; asm {$IFDEF TARGET_x64} PUSH RBX MOV EAX,1 CPUID POP RBX {$ELSE} PUSH EBX MOV EAX,1 {$IFDEF FPC} CPUID {$ELSE} DW $A20F // CPUID {$ENDIF} POP EBX {$ENDIF} end; function CPU_Features: Integer; asm {$IFDEF TARGET_x64} PUSH RBX MOV EAX,1 CPUID POP RBX MOV EAX,EDX {$ELSE} PUSH EBX MOV EAX,1 {$IFDEF FPC} CPUID {$ELSE} DW $A20F // CPUID {$ENDIF} POP EBX MOV EAX,EDX {$ENDIF} end; function CPU_ExtensionsAvailable: Boolean; asm {$IFDEF TARGET_x64} PUSH RBX MOV @Result, True MOV EAX, $80000000 CPUID CMP EAX, $80000000 JBE @NOEXTENSION JMP @EXIT @NOEXTENSION: MOV @Result, False @EXIT: POP RBX {$ELSE} PUSH EBX MOV @Result, True MOV EAX, $80000000 {$IFDEF FPC} CPUID {$ELSE} DW $A20F // CPUID {$ENDIF} CMP EAX, $80000000 JBE @NOEXTENSION JMP @EXIT @NOEXTENSION: MOV @Result, False @EXIT: POP EBX {$ENDIF} end; function CPU_ExtFeatures: Integer; asm {$IFDEF TARGET_x64} PUSH RBX MOV EAX, $80000001 CPUID POP RBX MOV EAX,EDX {$ELSE} PUSH EBX MOV EAX, $80000001 {$IFDEF FPC} CPUID {$ELSE} DW $A20F // CPUID {$ENDIF} POP EBX MOV EAX,EDX {$ENDIF} end; function HasInstructionSet(const InstructionSet: TCPUInstructionSet): Boolean; // Must be implemented for each target CPU on which specific functions rely begin Result := False; if not CPUID_Available then Exit; // no CPUID available if CPU_Signature shr 8 and $0F < 5 then Exit; // not a Pentium class case InstructionSet of ci3DNow, ci3DNowExt: {$IFNDEF FPC} if not CPU_ExtensionsAvailable or (CPU_ExtFeatures and CPUISChecks[InstructionSet] = 0) then {$ENDIF} Exit; ciEMMX: begin // check for SSE, necessary for Intel CPUs because they don't implement the // extended info if (CPU_Features and CPUISChecks[ciSSE] = 0) and (not CPU_ExtensionsAvailable or (CPU_ExtFeatures and CPUISChecks[ciEMMX] = 0)) then Exit; end; else if CPU_Features and CPUISChecks[InstructionSet] = 0 then Exit; // return -> instruction set not supported end; Result := True; end; 

You can call HasInstructionSet(ciSSE2) to find out what you need.

+7
source

Source: https://habr.com/ru/post/908771/


All Articles