1 /* Helper file for i386 platform. Runtime check for MMX/SSE/SSE2 support. 2 3 Copyright 2004 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, 20 Boston, MA 02111-1307, USA. */ 21 22 /* Used by 20020523-2.c and i386-sse-6.c, and possibly others. */ 23 /* Plagarized from 20020523-2.c. */ 24 /* Plagarized from gcc. */ 25 26 #define bit_CMOV (1 << 15) 27 #define bit_MMX (1 << 23) 28 #define bit_SSE (1 << 25) 29 #define bit_SSE2 (1 << 26) 30 31 #ifndef NOINLINE 32 #define NOINLINE __attribute__ ((noinline)) 33 #endif 34 35 unsigned int i386_cpuid (void) NOINLINE; 36 37 unsigned int NOINLINE 38 i386_cpuid (void) 39 { 40 int fl1, fl2; 41 42 #ifndef __x86_64__ 43 /* See if we can use cpuid. On AMD64 we always can. */ 44 __asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;" 45 "pushl %0; popfl; pushfl; popl %0; popfl" 46 : "=&r" (fl1), "=&r" (fl2) 47 : "i" (0x00200000)); 48 if (((fl1 ^ fl2) & 0x00200000) == 0) 49 return (0); 50 #endif 51 52 /* Host supports cpuid. See if cpuid gives capabilities, try 53 CPUID(0). Preserve %ebx and %ecx; cpuid insn clobbers these, we 54 don't need their CPUID values here, and %ebx may be the PIC 55 register. */ 56 #ifdef __x86_64__ 57 __asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx" 58 : "=a" (fl1) : "0" (0) : "rdx", "cc"); 59 #else 60 __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx" 61 : "=a" (fl1) : "0" (0) : "edx", "cc"); 62 #endif 63 if (fl1 == 0) 64 return (0); 65 66 /* Invoke CPUID(1), return %edx; caller can examine bits to 67 determine what's supported. */ 68 #ifdef __x86_64__ 69 __asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx" 70 : "=d" (fl2), "=a" (fl1) : "1" (1) : "cc"); 71 #else 72 __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx" 73 : "=d" (fl2), "=a" (fl1) : "1" (1) : "cc"); 74 #endif 75 76 return fl2; 77 } 78