/* 
 * $Id: cpuid.h,v 1.3 2009/04/06 05:43:23 karn Exp karn $
 * Copyright 2009, Phil Karn, KA9Q
 * Available under the terms of the GNU General Public License
 */

void illtrap(int);
char *brand_string(void);
void decode_cyrix_tlb(int);
void dointel(),doamd(),docyrix(),dogeode();
void putreg(unsigned int);
void showregs(unsigned int);
int scompare(const void *,const void *);
void show_cache(void);


extern char *Regnames[];

struct featureflag {
  char *abbrev;
  char *full;
};

void decode_feature_flags(struct featureflag table[],int reg);

extern struct featureflag Intel_standard_ecx[];
extern struct featureflag Intel_standard_edx[];
extern struct featureflag Intel_extended_ecx[];
extern struct featureflag Intel_extended_edx[];

extern struct featureflag AMD_standard_ecx[];
extern struct featureflag AMD_standard_edx[];
extern struct featureflag AMD_extended_ecx[];
extern struct featureflag AMD_extended_edx[];

#ifndef NULL
#define NULL ((void *)0)
#endif

/* Execute CPUID and stash output in array of 4 longs */
#ifdef __i386__
static inline void cpuid(unsigned int regs[4]){
  asm ("mov %0,%%edi; mov %%ebx,%%esi; mov  0(%%edi),%%eax; mov  4(%%edi),%%ebx; mov  8(%%edi),%%ecx; mov 12(%%edi),%%edx; \
        cpuid; \
        mov %%eax, 0(%%edi); mov %%ebx, 4(%%edi); mov %%ecx,8(%%edi); mov %%edx,12(%%edi); mov %%esi,%%ebx"
       : : "g"(regs) : "%eax","%ecx","%edx","%edi","%esi");
}
#else
static inline void cpuid(unsigned int regs[4]){
  asm ("push %%rbx; push %%rdi; mov %0,%%rdi;\
        mov  0(%%rdi),%%eax; \
        mov  4(%%rdi),%%ebx; \
        mov  8(%%rdi),%%ecx; \
        mov 12(%%rdi),%%edx; \
        cpuid; \
        mov %%eax, 0(%%rdi); \
        mov %%ebx, 4(%%rdi); \
        mov %%ecx,8(%%rdi);  \
        mov %%edx,12(%%rdi); \
        pop %%rdi; pop %%rbx"
       :
       : "g"(regs)
       : "%rax","%rcx","%rdx"); /* Also clobbers %rbx, but gcc flags an error if we list it */
}
#endif
