1/* 2 getcpucpuflags: get cpuflags for ia32 3 4 copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1 5 see COPYING and AUTHORS files in distribution or http:#mpg123.org 6 initially written by KIMURA Takuhiro (for 3DNow!) 7 extended for general use by Thomas Orgis 8 9 extern int getcpuid(struct cpuflags*) 10 or just 11 extern int getcpuid(unsigned int*) 12 where there is memory for 4 ints 13 -> the first set of idflags (basic cpu family info) 14 and the idflags, stdflags, std2flags, extflags written to the parameter 15 -> 0x00000000 (CPUID instruction not supported) 16*/ 17 18#include "mangle.h" 19 20.text 21 ALIGN4 22 23.globl ASM_NAME(getcpuflags) 24/* .type ASM_NAME(getcpuflags),@function */ 25ASM_NAME(getcpuflags): 26 pushl %ebp 27 movl %esp,%ebp 28 pushl %edx 29 pushl %ecx 30 pushl %ebx 31 pushl %esi 32/* get the int pointer for storing the flags */ 33 movl 8(%ebp), %esi 34/* does that one make sense? */ 35 movl $0x80000000,%eax 36/* now save the flags and do a check for cpuid availability */ 37 pushfl 38 pushfl 39 popl %eax 40 movl %eax,%ebx 41/* set that bit... */ 42 xorl $0x00200000,%eax 43 pushl %eax 44 popfl 45/* ...and read back the flags to see if it is understood */ 46 pushfl 47 popl %eax 48 popfl 49 cmpl %ebx,%eax 50 je .Lnocpuid 51/* In principle, I would have to check the CPU's identify first to be sure how to interpret the extended flags. */ 52/* now get the info, first extended */ 53 movl $0x0, 12(%esi) /* clear value */ 54 movl $0x0, 16(%esi) /* clear value */ 55/* only if supported... */ 56 movl $0x80000000, %eax 57 cpuid 58/* IDT CPUs should not change EAX, generally I hope that non-3DNow cpus do not set a bogus support level here. */ 59 cmpl $0x80000001, %eax 60 jb .Lnoextended /* Skip ext check without minimal support level. */ 61/* is supported, get flags value */ 62 movl $0x80000001,%eax 63 cpuid 64 movl %edx,12(%esi) 65.Lnoextended: 66/* then the other ones, called last to get the id flags in %eax for ret */ 67 movl $0x00000001,%eax 68 cpuid 69 movl %eax, (%esi) 70 movl %ecx, 4(%esi) 71 movl %edx, 8(%esi) 72/* check if xgetbv instruction is available */ 73 test $0x04000000, %ecx 74 jz .Lend 75 test $0x08000000, %ecx 76 jz .Lend 77 xor %ecx, %ecx 78 .byte 0x0f, 0x01, 0xd0 /* xgetbv instruction */ 79 movl %eax, 16(%esi) 80 movl (%esi), %eax 81 jmp .Lend 82 ALIGN4 83.Lnocpuid: 84/* error: set everything to zero */ 85 movl $0, %eax 86 movl $0, (%esi) 87 movl $0, 4(%esi) 88 movl $0, 8(%esi) 89 movl $0, 12(%esi) 90 movl $0, 16(%esi) 91 ALIGN4 92.Lend: 93/* return value are the id flags, still stored in %eax */ 94 popl %esi 95 popl %ebx 96 popl %ecx 97 popl %edx 98 movl %ebp,%esp 99 popl %ebp 100 ret 101 102NONEXEC_STACK 103