diff --git a/basis/cpu/x86/features/features-tests.factor b/basis/cpu/x86/features/features-tests.factor index 60c4bab8a1..8cc20b32b7 100644 --- a/basis/cpu/x86/features/features-tests.factor +++ b/basis/cpu/x86/features/features-tests.factor @@ -1,7 +1,9 @@ -USING: cpu.x86.features tools.test kernel sequences math math.order system ; +USING: cpu.x86.features tools.test kernel sequences math math.order +strings system io.binary ; IN: cpu.x86.features.tests -cpu x86? [ - [ t ] [ sse-version 0 42 between? ] unit-test - [ t ] [ [ 10000 [ ] times ] count-instructions integer? ] unit-test -] when +[ t ] [ sse-version 0 42 between? ] unit-test +[ t ] [ [ 10000 [ ] times ] count-instructions integer? ] unit-test + +{ "GenuineIntel" } +[ 0 cpuid [ 4 >le ] map { 1 3 2 } swap nths concat >string ] unit-test diff --git a/basis/cpu/x86/features/features.factor b/basis/cpu/x86/features/features.factor index 8be47f088c..487593de4e 100644 --- a/basis/cpu/x86/features/features.factor +++ b/basis/cpu/x86/features/features.factor @@ -4,7 +4,8 @@ USING: accessors assocs sequences alien alien.c-types combinators compiler compiler.codegen.labels compiler.units cpu.architecture cpu.x86.assembler cpu.x86.assembler.operands init io kernel locals math math.order math.parser memoize -namespaces system ; +namespaces system arrays specialized-arrays ; +SPECIALIZED-ARRAY: uint IN: cpu.x86.features = ; : sse4.2? ( -- ? ) sse-version 42 >= ; +HOOK: (cpuid) cpu ( n regs -- ) + +M: x86.32 (cpuid) ( n regs -- ) + void { uint void* } cdecl [ + ! Save ds-reg, rs-reg + EDI PUSH + EAX ESP 4 [+] MOV + CPUID + EDI ESP 8 [+] MOV + EDI [] EAX MOV + EDI 4 [+] EBX MOV + EDI 8 [+] ECX MOV + EDI 12 [+] EDX MOV + EDI POP + ] alien-assembly ; + +M: x86.64 (cpuid) ( n regs -- ) + void { uint void* } cdecl [ + RAX RDI MOV + CPUID + RSI [] EAX MOV + RSI 4 [+] EBX MOV + RSI 8 [+] ECX MOV + RSI 12 [+] EDX MOV + ] alien-assembly ; + +: cpuid ( n -- 4array ) + 4 [ (cpuid) ] keep >array ; + : popcnt? ( -- ? ) bool { } cdecl [ return-reg 1 MOV