#include <stdio.h>
#include <limits.h>
#include <mach-o/fat.h>
#include <stuff/best_arch.h>
__private_extern__
struct fat_arch *
cpusubtype_findbestarch(
cpu_type_t cputype,
cpu_subtype_t cpusubtype,
struct fat_arch *fat_archs,
unsigned long nfat_archs)
{
unsigned long i, lowest_family, lowest_model, lowest_index;
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype == cputype &&
fat_archs[i].cpusubtype == cpusubtype)
return(fat_archs + i);
}
switch(cputype){
case CPU_TYPE_I386:
switch(cpusubtype){
default:
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_PENT)
return(fat_archs + i);
}
case CPU_SUBTYPE_PENT:
case CPU_SUBTYPE_486SX:
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_486)
return(fat_archs + i);
}
break;
case CPU_SUBTYPE_I386_ALL:
case CPU_SUBTYPE_486:
break;
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_I386_ALL)
return(fat_archs + i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_486)
return(fat_archs + i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_486SX)
return(fat_archs + i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_586)
return(fat_archs + i);
}
lowest_family = CPU_SUBTYPE_INTEL_FAMILY_MAX + 1;
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(CPU_SUBTYPE_INTEL_FAMILY(fat_archs[i].cpusubtype) <
lowest_family)
lowest_family = CPU_SUBTYPE_INTEL_FAMILY(
fat_archs[i].cpusubtype);
}
if(lowest_family == CPU_SUBTYPE_INTEL_FAMILY_MAX + 1)
return(NULL);
lowest_model = ULONG_MAX;
lowest_index = -1;
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(CPU_SUBTYPE_INTEL_FAMILY(fat_archs[i].cpusubtype) ==
lowest_family){
if(CPU_SUBTYPE_INTEL_MODEL(fat_archs[i].cpusubtype) <
lowest_model){
lowest_model = CPU_SUBTYPE_INTEL_MODEL(
fat_archs[i].cpusubtype);
lowest_index = i;
}
}
}
return(fat_archs + lowest_index);
case CPU_TYPE_MC680x0:
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_MC680x0_ALL)
return(fat_archs + i);
}
if(cpusubtype == CPU_SUBTYPE_MC680x0_ALL){
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_MC68040)
return(fat_archs + i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_MC68030_ONLY)
return(fat_archs + i);
}
}
break;
case CPU_TYPE_POWERPC:
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_7450)
return(fat_archs + i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_7400)
return(fat_archs + i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_750)
return(fat_archs + i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_604e)
return(fat_archs + i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_604)
return(fat_archs + i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_603ev)
return(fat_archs + i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_603e)
return(fat_archs + i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_603)
return(fat_archs + i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_ALL)
return(fat_archs + i);
}
break;
case CPU_TYPE_MC88000:
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_MC88000_ALL)
return(fat_archs + i);
}
break;
case CPU_TYPE_I860:
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_I860_ALL)
return(fat_archs + i);
}
break;
case CPU_TYPE_HPPA:
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_HPPA_ALL)
return(fat_archs + i);
}
break;
case CPU_TYPE_SPARC:
for(i = 0; i < nfat_archs; i++){
if(fat_archs[i].cputype != cputype)
continue;
if(fat_archs[i].cpusubtype == CPU_SUBTYPE_SPARC_ALL)
return(fat_archs + i);
}
break;
default:
return(NULL);
}
return(NULL);
}
__private_extern__
cpu_subtype_t
cpusubtype_combine(
cpu_type_t cputype,
cpu_subtype_t cpusubtype1,
cpu_subtype_t cpusubtype2)
{
if(cpusubtype1 == cpusubtype2)
return(cpusubtype1);
switch(cputype){
case CPU_TYPE_I386:
if((cpusubtype1 == CPU_SUBTYPE_I386_ALL ||
cpusubtype1 == CPU_SUBTYPE_486 ||
cpusubtype1 == CPU_SUBTYPE_486SX ||
cpusubtype1 == CPU_SUBTYPE_586) &&
(cpusubtype2 == CPU_SUBTYPE_I386_ALL ||
cpusubtype2 == CPU_SUBTYPE_486 ||
cpusubtype2 == CPU_SUBTYPE_486SX ||
cpusubtype2 == CPU_SUBTYPE_586)){
if(cpusubtype1 == CPU_SUBTYPE_586 ||
cpusubtype2 == CPU_SUBTYPE_586)
return(CPU_SUBTYPE_586);
if(cpusubtype1 == CPU_SUBTYPE_486SX ||
cpusubtype2 == CPU_SUBTYPE_486SX)
return(CPU_SUBTYPE_486SX);
if(cpusubtype1 == CPU_SUBTYPE_486 ||
cpusubtype2 == CPU_SUBTYPE_486)
return(CPU_SUBTYPE_486);
break;
}
if(CPU_SUBTYPE_INTEL_MODEL(cpusubtype1) ==
CPU_SUBTYPE_INTEL_MODEL_ALL)
return(cpusubtype2);
if(CPU_SUBTYPE_INTEL_MODEL(cpusubtype2) ==
CPU_SUBTYPE_INTEL_MODEL_ALL)
return(cpusubtype1);
return((cpu_subtype_t)-1);
break;
case CPU_TYPE_MC680x0:
if(cpusubtype1 != CPU_SUBTYPE_MC680x0_ALL &&
cpusubtype1 != CPU_SUBTYPE_MC68030_ONLY &&
cpusubtype1 != CPU_SUBTYPE_MC68040)
return((cpu_subtype_t)-1);
if(cpusubtype2 != CPU_SUBTYPE_MC680x0_ALL &&
cpusubtype2 != CPU_SUBTYPE_MC68030_ONLY &&
cpusubtype2 != CPU_SUBTYPE_MC68040)
return((cpu_subtype_t)-1);
if(cpusubtype1 == CPU_SUBTYPE_MC68030_ONLY &&
cpusubtype2 == CPU_SUBTYPE_MC68040)
return((cpu_subtype_t)-1);
if(cpusubtype1 == CPU_SUBTYPE_MC68040 &&
cpusubtype2 == CPU_SUBTYPE_MC68030_ONLY)
return((cpu_subtype_t)-1);
if(cpusubtype1 == CPU_SUBTYPE_MC68030_ONLY ||
cpusubtype2 == CPU_SUBTYPE_MC68030_ONLY)
return(CPU_SUBTYPE_MC68030_ONLY);
if(cpusubtype1 == CPU_SUBTYPE_MC68040 ||
cpusubtype2 == CPU_SUBTYPE_MC68040)
return(CPU_SUBTYPE_MC68040);
break;
case CPU_TYPE_POWERPC:
if(cpusubtype1 == CPU_SUBTYPE_POWERPC_ALL)
return(cpusubtype2);
if(cpusubtype2 == CPU_SUBTYPE_POWERPC_ALL)
return(cpusubtype1);
if(cpusubtype1 == CPU_SUBTYPE_POWERPC_601 ||
cpusubtype2 == CPU_SUBTYPE_POWERPC_601)
return(CPU_SUBTYPE_POWERPC_601);
return(CPU_SUBTYPE_POWERPC_ALL);
break;
case CPU_TYPE_MC88000:
if(cpusubtype1 != CPU_SUBTYPE_MC88000_ALL &&
cpusubtype1 != CPU_SUBTYPE_MC88110)
return((cpu_subtype_t)-1);
if(cpusubtype2 != CPU_SUBTYPE_MC88000_ALL &&
cpusubtype2 != CPU_SUBTYPE_MC88110)
return((cpu_subtype_t)-1);
if(cpusubtype1 == CPU_SUBTYPE_MC88110 ||
cpusubtype2 == CPU_SUBTYPE_MC88110)
return(CPU_SUBTYPE_MC88110);
break;
case CPU_TYPE_I860:
if(cpusubtype1 != CPU_SUBTYPE_I860_ALL &&
cpusubtype1 != CPU_SUBTYPE_I860_860)
return((cpu_subtype_t)-1);
if(cpusubtype2 != CPU_SUBTYPE_I860_ALL &&
cpusubtype2 != CPU_SUBTYPE_I860_860)
return((cpu_subtype_t)-1);
if(cpusubtype1 == CPU_SUBTYPE_I860_860 ||
cpusubtype2 == CPU_SUBTYPE_I860_860)
return(CPU_SUBTYPE_I860_860);
break;
case CPU_TYPE_HPPA:
if(cpusubtype1 != CPU_SUBTYPE_HPPA_ALL &&
cpusubtype1 != CPU_SUBTYPE_HPPA_7100LC)
return((cpu_subtype_t)-1);
if(cpusubtype2 != CPU_SUBTYPE_HPPA_ALL &&
cpusubtype2 != CPU_SUBTYPE_HPPA_7100LC)
return((cpu_subtype_t)-1);
return(CPU_SUBTYPE_HPPA_7100LC);
break;
case CPU_TYPE_SPARC:
if(cpusubtype1 != CPU_SUBTYPE_SPARC_ALL)
return((cpu_subtype_t)-1);
if(cpusubtype2 != CPU_SUBTYPE_SPARC_ALL)
return((cpu_subtype_t)-1);
break;
default:
return((cpu_subtype_t)-1);
}
return((cpu_subtype_t)-1);
}