Merge pull request #8 from biergaizi/upstream
[darwin-xtools.git] / cctools / libmacho / arch.c
blob7edf362286f0602a3c8e7838eff56c90fecef59d
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 * Copyright (c) 1993 NeXT Computer, Inc.
26 * Architecture computing functions.
28 * HISTORY
30 * 11 April 1997
31 * Update m98k to ppc and removed the never supported architectures (mips,
32 * and vax). Apple Computer, Inc.
34 * 4 February 1993 Lennart Lovstrand <lennart@next.com>
35 * Redesigned to use NXArchInfo based names and signatures.
37 * Originally written at NeXT, Inc.
40 #ifndef RLD
41 #include <stdint.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <limits.h>
47 #include "mach/machine.h"
48 #include "mach/mach.h"
49 #include "stuff/openstep_mach.h"
50 #include <mach-o/fat.h>
51 #include <mach-o/arch.h>
53 /* The array of all currently know architecture flags (terminated with an entry
54 * with all zeros). Pointer to this returned with NXGetAllArchInfos().
56 static const NXArchInfo ArchInfoTable[] = {
57 /* architecture families */
58 {"hppa", CPU_TYPE_HPPA, CPU_SUBTYPE_HPPA_ALL, NX_BigEndian,
59 "HP-PA"},
60 {"i386", CPU_TYPE_I386, CPU_SUBTYPE_I386_ALL, NX_LittleEndian,
61 "Intel 80x86"},
62 { "x86_64", CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL, NX_LittleEndian,
63 "Intel x86-64" },
64 { "x86_64h", CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_H, NX_LittleEndian,
65 "Intel x86-64h Haswell" },
66 {"i860", CPU_TYPE_I860, CPU_SUBTYPE_I860_ALL, NX_BigEndian,
67 "Intel 860"},
68 {"m68k", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC680x0_ALL, NX_BigEndian,
69 "Motorola 68K"},
70 {"m88k", CPU_TYPE_MC88000, CPU_SUBTYPE_MC88000_ALL, NX_BigEndian,
71 "Motorola 88K"},
72 {"ppc", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL, NX_BigEndian,
73 "PowerPC"},
74 {"ppc64", CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_ALL, NX_BigEndian,
75 "PowerPC 64-bit"},
76 {"sparc", CPU_TYPE_SPARC, CPU_SUBTYPE_SPARC_ALL, NX_BigEndian,
77 "SPARC"},
78 {"arm", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_ALL, NX_LittleEndian,
79 "ARM"},
80 {"arm64", CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL, NX_LittleEndian,
81 "ARM64"},
82 {"any", CPU_TYPE_ANY, CPU_SUBTYPE_MULTIPLE, NX_UnknownByteOrder,
83 "Architecture Independent"},
84 {"veo", CPU_TYPE_VEO, CPU_SUBTYPE_VEO_ALL, NX_BigEndian,
85 "veo"},
86 /* specific architecture implementations */
87 {"hppa7100LC", CPU_TYPE_HPPA, CPU_SUBTYPE_HPPA_7100LC, NX_BigEndian,
88 "HP-PA 7100LC"},
89 {"m68030", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68030_ONLY, NX_BigEndian,
90 "Motorola 68030"},
91 {"m68040", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68040, NX_BigEndian,
92 "Motorola 68040"},
93 {"i486", CPU_TYPE_I386, CPU_SUBTYPE_486, NX_LittleEndian,
94 "Intel 80486"},
95 {"i486SX", CPU_TYPE_I386, CPU_SUBTYPE_486SX, NX_LittleEndian,
96 "Intel 80486SX"},
97 {"pentium",CPU_TYPE_I386, CPU_SUBTYPE_PENT, NX_LittleEndian,
98 "Intel Pentium"}, /* same as 586 */
99 {"i586", CPU_TYPE_I386, CPU_SUBTYPE_586, NX_LittleEndian,
100 "Intel 80586"},
101 {"pentpro", CPU_TYPE_I386, CPU_SUBTYPE_PENTPRO, NX_LittleEndian,
102 "Intel Pentium Pro"}, /* same as 686 */
103 {"i686", CPU_TYPE_I386, CPU_SUBTYPE_PENTPRO, NX_LittleEndian,
104 "Intel Pentium Pro"},
105 {"pentIIm3", CPU_TYPE_I386, CPU_SUBTYPE_PENTII_M3, NX_LittleEndian,
106 "Intel Pentium II Model 3" },
107 {"pentIIm5", CPU_TYPE_I386, CPU_SUBTYPE_PENTII_M5, NX_LittleEndian,
108 "Intel Pentium II Model 5" },
109 {"pentium4", CPU_TYPE_I386, CPU_SUBTYPE_PENTIUM_4, NX_LittleEndian,
110 "Intel Pentium 4" },
111 { "x86_64h", CPU_TYPE_I386, CPU_SUBTYPE_X86_64_H, NX_LittleEndian,
112 "Intel x86-64h Haswell" },
113 {"ppc601", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_601, NX_BigEndian,
114 "PowerPC 601" },
115 {"ppc603", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_603, NX_BigEndian,
116 "PowerPC 603" },
117 {"ppc603e",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_603e, NX_BigEndian,
118 "PowerPC 603e" },
119 {"ppc603ev",CPU_TYPE_POWERPC,CPU_SUBTYPE_POWERPC_603ev,NX_BigEndian,
120 "PowerPC 603ev" },
121 {"ppc604", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_604, NX_BigEndian,
122 "PowerPC 604" },
123 {"ppc604e",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_604e, NX_BigEndian,
124 "PowerPC 604e" },
125 {"ppc750", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_750, NX_BigEndian,
126 "PowerPC 750" },
127 {"ppc7400",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7400, NX_BigEndian,
128 "PowerPC 7400" },
129 {"ppc7450",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7450, NX_BigEndian,
130 "PowerPC 7450" },
131 {"ppc970", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_970, NX_BigEndian,
132 "PowerPC 970" },
133 {"ppc970-64", CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_970, NX_BigEndian,
134 "PowerPC 970 64-bit"},
135 {"armv4t", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V4T, NX_LittleEndian,
136 "arm v4t"},
137 {"armv5", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V5TEJ, NX_LittleEndian,
138 "arm v5"},
139 {"xscale", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_XSCALE, NX_LittleEndian,
140 "arm xscale"},
141 {"armv6", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6, NX_LittleEndian,
142 "arm v6"},
143 {"armv6m", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6M, NX_LittleEndian,
144 "arm v6m"},
145 {"armv7", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7, NX_LittleEndian,
146 "arm v7"},
147 {"armv7f", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7F, NX_LittleEndian,
148 "arm v7f"},
149 {"armv7s", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S, NX_LittleEndian,
150 "arm v7s"},
151 {"armv7k", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7K, NX_LittleEndian,
152 "arm v7k"},
153 {"armv7m", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7M, NX_LittleEndian,
154 "arm v7m"},
155 {"armv7em",CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7EM, NX_LittleEndian,
156 "arm v7em"},
157 {"armv8", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V8, NX_LittleEndian,
158 "arm v8"},
159 {"arm64",CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_V8, NX_LittleEndian,
160 "arm64 v8"},
161 {"little", CPU_TYPE_ANY, CPU_SUBTYPE_LITTLE_ENDIAN, NX_LittleEndian,
162 "Little Endian"},
163 {"big", CPU_TYPE_ANY, CPU_SUBTYPE_BIG_ENDIAN, NX_BigEndian,
164 "Big Endian"},
165 {"veo1",CPU_TYPE_VEO, CPU_SUBTYPE_VEO_1, NX_BigEndian,
166 "veo 1" },
167 {"veo2",CPU_TYPE_VEO, CPU_SUBTYPE_VEO_2, NX_BigEndian,
168 "veo 2" },
169 {NULL, 0, 0, 0,
170 NULL}
174 * NXGetAllArchInfos() returns a pointer to an array of all currently know
175 * architecture flags (terminated with an entry with all zeros).
177 const
178 NXArchInfo *
179 NXGetAllArchInfos(void)
181 return(ArchInfoTable);
185 * NXGetLocalArchInfo() returns the NXArchInfo matching the cputype and
186 * cpusubtype of the local host. NULL is returned if there is no matching
187 * entry in the ArchInfoTable.
189 const
190 NXArchInfo *
191 NXGetLocalArchInfo(void)
193 struct host_basic_info hbi;
194 kern_return_t ret;
195 unsigned int count;
196 mach_port_t my_mach_host_self;
198 count = HOST_BASIC_INFO_COUNT;
199 my_mach_host_self = mach_host_self();
200 ret = host_info(my_mach_host_self, HOST_BASIC_INFO, (host_info_t)&hbi,
201 &count);
202 mach_port_deallocate(mach_task_self(), my_mach_host_self);
203 if(ret != KERN_SUCCESS)
204 return(NULL);
207 * There is a "bug" in the kernel for compatiblity that on
208 * an 030 machine host_info() returns cpusubtype
209 * CPU_SUBTYPE_MC680x0_ALL and not CPU_SUBTYPE_MC68030_ONLY.
211 if(hbi.cpu_type == CPU_TYPE_MC680x0 &&
212 hbi.cpu_subtype == CPU_SUBTYPE_MC680x0_ALL)
213 hbi.cpu_subtype = CPU_SUBTYPE_MC68030_ONLY;
215 return(NXGetArchInfoFromCpuType(hbi.cpu_type, hbi.cpu_subtype));
219 * NXGetArchInfoFromName() is passed an architecture name (like "m68k")
220 * and returns the matching NXArchInfo struct, or NULL if none is found.
222 const
223 NXArchInfo *
224 NXGetArchInfoFromName(
225 const char *name)
227 const NXArchInfo *ai;
229 for(ai = ArchInfoTable; ai->name != NULL; ai++)
230 if(strcmp(ai->name, name) == 0)
231 return(ai);
233 return(NULL);
237 * NXGetArchInfoFromName() is passed a cputype and cpusubtype and returns
238 * the matching NXArchInfo struct, or NULL if none is found. If the
239 * cpusubtype is given as CPU_SUBTYPE_MULTIPLE, the first entry that
240 * matches the given cputype is returned. This is the NXArchInfo struct
241 * describing the CPU "family".
243 const
244 NXArchInfo *
245 NXGetArchInfoFromCpuType(
246 cpu_type_t cputype,
247 cpu_subtype_t cpusubtype)
249 const NXArchInfo *ai;
250 NXArchInfo *q;
252 for(ai = ArchInfoTable; ai->name != NULL; ai++)
253 if(ai->cputype == cputype &&
254 (cpusubtype == CPU_SUBTYPE_MULTIPLE ||
255 ((ai->cpusubtype & ~CPU_SUBTYPE_MASK) ==
256 (cpusubtype & ~CPU_SUBTYPE_MASK))))
257 return(ai);
259 if(cputype == CPU_TYPE_I386){
260 q = malloc(sizeof(NXArchInfo));
261 for(ai = ArchInfoTable; ai->name != NULL; ai++){
262 if(ai->cputype == cputype){
263 *q = *ai;
264 break;
267 q->cpusubtype = cpusubtype;
268 q->description = malloc(sizeof("Intel family model ") + 2 + 8);
269 if(q->description == NULL){
270 free(q);
271 return(NULL);
273 sprintf((char *)q->description, "Intel family %u model %u",
274 CPU_SUBTYPE_INTEL_FAMILY(cpusubtype & ~CPU_SUBTYPE_MASK),
275 CPU_SUBTYPE_INTEL_MODEL(cpusubtype & ~CPU_SUBTYPE_MASK));
276 return((const NXArchInfo *)q);
278 else if(cputype == CPU_TYPE_POWERPC){
279 q = malloc(sizeof(NXArchInfo));
280 for(ai = ArchInfoTable; ai->name != NULL; ai++){
281 if(ai->cputype == cputype){
282 *q = *ai;
283 break;
286 q->cpusubtype = cpusubtype;
287 q->description = malloc(sizeof("PowerPC cpusubtype ") + 10);
288 if(q->description == NULL){
289 free(q);
290 return(NULL);
292 sprintf((char *)q->description, "PowerPC cpusubtype %u", cpusubtype);
293 return((const NXArchInfo *)q);
296 return(NULL);
300 * internal_NXFindBestFatArch() is passed a cputype and cpusubtype and a
301 * either set of fat_arch structs or fat_arch_64 structs and selects the best
302 * one that matches (if any) and returns an index to the array of structs or
303 * -1 if none works for the cputype and cpusubtype. The fat_arch structs or
304 * fat_arch_64 structs must be in the host byte sex and correct such that the
305 * fat_archs really points to enough memory for nfat_arch structs. It is
306 * possible that this routine could fail if new cputypes or cpusubtypes are
307 * added and an old version of this routine is used. But if there is an exact
308 * match between the cputype and cpusubtype and one of the structs this routine
309 * will always succeed.
311 int32_t
312 internal_NXFindBestFatArch(
313 cpu_type_t cputype,
314 cpu_subtype_t cpusubtype,
315 struct fat_arch *fat_archs,
316 struct fat_arch_64 *fat_archs64,
317 uint32_t nfat_archs)
319 uint32_t i;
320 int32_t lowest_family, lowest_model, lowest_index;
321 cpu_type_t fat_cputype;
322 cpu_subtype_t fat_cpusubtype;
325 * Look for the first exact match.
327 for(i = 0; i < nfat_archs; i++){
328 if(fat_archs64 != NULL){
329 fat_cputype = fat_archs64[i].cputype;
330 fat_cpusubtype = fat_archs64[i].cpusubtype;
332 else{
333 fat_cputype = fat_archs[i].cputype;
334 fat_cpusubtype = fat_archs[i].cpusubtype;
336 if(fat_cputype == cputype &&
337 (fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
338 (cpusubtype & ~CPU_SUBTYPE_MASK))
339 return(i);
343 * An exact match was not found so find the next best match which is
344 * cputype dependent.
346 switch(cputype){
347 case CPU_TYPE_I386:
348 switch(cpusubtype & ~CPU_SUBTYPE_MASK){
349 default:
351 * Intel cpusubtypes after the pentium (same as 586) are handled
352 * such that they require an exact match or they can use the
353 * pentium. If that is not found call into the loop for the
354 * earilier subtypes.
356 for(i = 0; i < nfat_archs; i++){
357 if(fat_archs64 != NULL){
358 fat_cputype = fat_archs64[i].cputype;
359 fat_cpusubtype = fat_archs64[i].cpusubtype;
361 else{
362 fat_cputype = fat_archs[i].cputype;
363 fat_cpusubtype = fat_archs[i].cpusubtype;
365 if(fat_cputype != cputype)
366 continue;
367 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
368 CPU_SUBTYPE_PENT)
369 return(i);
371 case CPU_SUBTYPE_PENT:
372 case CPU_SUBTYPE_486SX:
374 * Since an exact match as not found look for the i486 else
375 * break into the loop to look for the i386_ALL.
377 for(i = 0; i < nfat_archs; i++){
378 if(fat_archs64 != NULL){
379 fat_cputype = fat_archs64[i].cputype;
380 fat_cpusubtype = fat_archs64[i].cpusubtype;
382 else{
383 fat_cputype = fat_archs[i].cputype;
384 fat_cpusubtype = fat_archs[i].cpusubtype;
386 if(fat_cputype != cputype)
387 continue;
388 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
389 CPU_SUBTYPE_486)
390 return(i);
392 break;
393 case CPU_SUBTYPE_I386_ALL:
394 /* case CPU_SUBTYPE_I386: same as above */
395 case CPU_SUBTYPE_486:
396 break;
398 for(i = 0; i < nfat_archs; i++){
399 if(fat_archs64 != NULL){
400 fat_cputype = fat_archs64[i].cputype;
401 fat_cpusubtype = fat_archs64[i].cpusubtype;
403 else{
404 fat_cputype = fat_archs[i].cputype;
405 fat_cpusubtype = fat_archs[i].cpusubtype;
407 if(fat_cputype != cputype)
408 continue;
409 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
410 CPU_SUBTYPE_I386_ALL)
411 return(i);
415 * A match failed, promote as little as possible.
417 for(i = 0; i < nfat_archs; i++){
418 if(fat_archs64 != NULL){
419 fat_cputype = fat_archs64[i].cputype;
420 fat_cpusubtype = fat_archs64[i].cpusubtype;
422 else{
423 fat_cputype = fat_archs[i].cputype;
424 fat_cpusubtype = fat_archs[i].cpusubtype;
426 if(fat_cputype != cputype)
427 continue;
428 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
429 CPU_SUBTYPE_486)
430 return(i);
432 for(i = 0; i < nfat_archs; i++){
433 if(fat_archs64 != NULL){
434 fat_cputype = fat_archs64[i].cputype;
435 fat_cpusubtype = fat_archs64[i].cpusubtype;
437 else{
438 fat_cputype = fat_archs[i].cputype;
439 fat_cpusubtype = fat_archs[i].cpusubtype;
441 if(fat_cputype != cputype)
442 continue;
443 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
444 CPU_SUBTYPE_486SX)
445 return(i);
447 for(i = 0; i < nfat_archs; i++){
448 if(fat_archs64 != NULL){
449 fat_cputype = fat_archs64[i].cputype;
450 fat_cpusubtype = fat_archs64[i].cpusubtype;
452 else{
453 fat_cputype = fat_archs[i].cputype;
454 fat_cpusubtype = fat_archs[i].cpusubtype;
456 if(fat_cputype != cputype)
457 continue;
458 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
459 CPU_SUBTYPE_586)
460 return(i);
463 * Now look for the lowest family and in that the lowest model.
465 lowest_family = CPU_SUBTYPE_INTEL_FAMILY_MAX + 1;
466 for(i = 0; i < nfat_archs; i++){
467 if(fat_archs64 != NULL){
468 fat_cputype = fat_archs64[i].cputype;
469 fat_cpusubtype = fat_archs64[i].cpusubtype;
471 else{
472 fat_cputype = fat_archs[i].cputype;
473 fat_cpusubtype = fat_archs[i].cpusubtype;
475 if(fat_cputype != cputype)
476 continue;
477 if(CPU_SUBTYPE_INTEL_FAMILY(fat_cpusubtype &
478 ~CPU_SUBTYPE_MASK) < lowest_family)
479 lowest_family = CPU_SUBTYPE_INTEL_FAMILY(
480 fat_cpusubtype & ~CPU_SUBTYPE_MASK);
482 /* if no intel cputypes found return NULL */
483 if(lowest_family == CPU_SUBTYPE_INTEL_FAMILY_MAX + 1)
484 return(-1);
485 lowest_model = INT_MAX;
486 lowest_index = -1;
487 for(i = 0; i < nfat_archs; i++){
488 if(fat_archs64 != NULL){
489 fat_cputype = fat_archs64[i].cputype;
490 fat_cpusubtype = fat_archs64[i].cpusubtype;
492 else{
493 fat_cputype = fat_archs[i].cputype;
494 fat_cpusubtype = fat_archs[i].cpusubtype;
496 if(fat_cputype != cputype)
497 continue;
498 if(CPU_SUBTYPE_INTEL_FAMILY(fat_cpusubtype &
499 ~CPU_SUBTYPE_MASK) == lowest_family){
500 if(CPU_SUBTYPE_INTEL_MODEL(fat_cpusubtype &
501 ~CPU_SUBTYPE_MASK) < lowest_model){
502 lowest_model = CPU_SUBTYPE_INTEL_MODEL(
503 fat_cpusubtype &
504 ~CPU_SUBTYPE_MASK);
505 lowest_index = i;
509 return(lowest_index);
510 case CPU_TYPE_X86_64:
511 for(i = 0; i < nfat_archs; i++){
512 if(fat_archs64 != NULL){
513 fat_cputype = fat_archs64[i].cputype;
514 fat_cpusubtype = fat_archs64[i].cpusubtype;
516 else{
517 fat_cputype = fat_archs[i].cputype;
518 fat_cpusubtype = fat_archs[i].cpusubtype;
520 if(fat_cputype != cputype)
521 continue;
522 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
523 CPU_SUBTYPE_X86_64_ALL)
524 return(i);
526 break;
527 case CPU_TYPE_MC680x0:
528 for(i = 0; i < nfat_archs; i++){
529 if(fat_archs64 != NULL){
530 fat_cputype = fat_archs64[i].cputype;
531 fat_cpusubtype = fat_archs64[i].cpusubtype;
533 else{
534 fat_cputype = fat_archs[i].cputype;
535 fat_cpusubtype = fat_archs[i].cpusubtype;
537 if(fat_cputype != cputype)
538 continue;
539 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
540 CPU_SUBTYPE_MC680x0_ALL)
541 return(i);
544 * Try to promote if starting from CPU_SUBTYPE_MC680x0_ALL and
545 * favor the CPU_SUBTYPE_MC68040 over the CPU_SUBTYPE_MC68030_ONLY.
547 if((cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC680x0_ALL){
548 for(i = 0; i < nfat_archs; i++){
549 if(fat_archs64 != NULL){
550 fat_cputype = fat_archs64[i].cputype;
551 fat_cpusubtype = fat_archs64[i].cpusubtype;
553 else{
554 fat_cputype = fat_archs[i].cputype;
555 fat_cpusubtype = fat_archs[i].cpusubtype;
557 if(fat_cputype != cputype)
558 continue;
559 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
560 CPU_SUBTYPE_MC68040)
561 return(i);
563 for(i = 0; i < nfat_archs; i++){
564 if(fat_archs64 != NULL){
565 fat_cputype = fat_archs64[i].cputype;
566 fat_cpusubtype = fat_archs64[i].cpusubtype;
568 else{
569 fat_cputype = fat_archs[i].cputype;
570 fat_cpusubtype = fat_archs[i].cpusubtype;
572 if(fat_cputype != cputype)
573 continue;
574 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
575 CPU_SUBTYPE_MC68030_ONLY)
576 return(i);
579 break;
580 case CPU_TYPE_POWERPC:
582 * An exact match as not found. So for all the PowerPC subtypes
583 * pick the subtype from the following order starting from a subtype
584 * that will work (contains 64-bit instructions or altivec if
585 * needed):
586 * 970, 7450, 7400, 750, 604e, 604, 603ev, 603e, 603, ALL
587 * Note the 601 is NOT in the list above. It is only picked via
588 * an exact match. For an unknown subtype pick only the ALL type if
589 * it exists.
591 switch(cpusubtype & ~CPU_SUBTYPE_MASK){
592 case CPU_SUBTYPE_POWERPC_ALL:
594 * The CPU_SUBTYPE_POWERPC_ALL is only used by the development
595 * environment tools when building a generic ALL type binary.
596 * In the case of a non-exact match we pick the most current
597 * processor.
599 case CPU_SUBTYPE_POWERPC_970:
600 for(i = 0; i < nfat_archs; i++){
601 if(fat_archs64 != NULL){
602 fat_cputype = fat_archs64[i].cputype;
603 fat_cpusubtype = fat_archs64[i].cpusubtype;
605 else{
606 fat_cputype = fat_archs[i].cputype;
607 fat_cpusubtype = fat_archs[i].cpusubtype;
609 if(fat_cputype != cputype)
610 continue;
611 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
612 CPU_SUBTYPE_POWERPC_970)
613 return(i);
615 case CPU_SUBTYPE_POWERPC_7450:
616 case CPU_SUBTYPE_POWERPC_7400:
617 for(i = 0; i < nfat_archs; i++){
618 if(fat_archs64 != NULL){
619 fat_cputype = fat_archs64[i].cputype;
620 fat_cpusubtype = fat_archs64[i].cpusubtype;
622 else{
623 fat_cputype = fat_archs[i].cputype;
624 fat_cpusubtype = fat_archs[i].cpusubtype;
626 if(fat_cputype != cputype)
627 continue;
628 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
629 CPU_SUBTYPE_POWERPC_7450)
630 return(i);
632 for(i = 0; i < nfat_archs; i++){
633 if(fat_archs64 != NULL){
634 fat_cputype = fat_archs64[i].cputype;
635 fat_cpusubtype = fat_archs64[i].cpusubtype;
637 else{
638 fat_cputype = fat_archs[i].cputype;
639 fat_cpusubtype = fat_archs[i].cpusubtype;
641 if(fat_cputype != cputype)
642 continue;
643 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
644 CPU_SUBTYPE_POWERPC_7400)
645 return(i);
647 case CPU_SUBTYPE_POWERPC_750:
648 case CPU_SUBTYPE_POWERPC_604e:
649 case CPU_SUBTYPE_POWERPC_604:
650 case CPU_SUBTYPE_POWERPC_603ev:
651 case CPU_SUBTYPE_POWERPC_603e:
652 case CPU_SUBTYPE_POWERPC_603:
653 for(i = 0; i < nfat_archs; i++){
654 if(fat_archs64 != NULL){
655 fat_cputype = fat_archs64[i].cputype;
656 fat_cpusubtype = fat_archs64[i].cpusubtype;
658 else{
659 fat_cputype = fat_archs[i].cputype;
660 fat_cpusubtype = fat_archs[i].cpusubtype;
662 if(fat_cputype != cputype)
663 continue;
664 if((fat_cpusubtype & CPU_SUBTYPE_MASK) ==
665 CPU_SUBTYPE_POWERPC_750)
666 return(i);
668 for(i = 0; i < nfat_archs; i++){
669 if(fat_archs64 != NULL){
670 fat_cputype = fat_archs64[i].cputype;
671 fat_cpusubtype = fat_archs64[i].cpusubtype;
673 else{
674 fat_cputype = fat_archs[i].cputype;
675 fat_cpusubtype = fat_archs[i].cpusubtype;
677 if(fat_cputype != cputype)
678 continue;
679 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
680 CPU_SUBTYPE_POWERPC_604e)
681 return(i);
683 for(i = 0; i < nfat_archs; i++){
684 if(fat_archs64 != NULL){
685 fat_cputype = fat_archs64[i].cputype;
686 fat_cpusubtype = fat_archs64[i].cpusubtype;
688 else{
689 fat_cputype = fat_archs[i].cputype;
690 fat_cpusubtype = fat_archs[i].cpusubtype;
692 if(fat_cputype != cputype)
693 continue;
694 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
695 CPU_SUBTYPE_POWERPC_604)
696 return(i);
698 for(i = 0; i < nfat_archs; i++){
699 if(fat_archs64 != NULL){
700 fat_cputype = fat_archs64[i].cputype;
701 fat_cpusubtype = fat_archs64[i].cpusubtype;
703 else{
704 fat_cputype = fat_archs[i].cputype;
705 fat_cpusubtype = fat_archs[i].cpusubtype;
707 if((fat_cputype & ~CPU_SUBTYPE_MASK) != cputype)
708 continue;
709 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
710 CPU_SUBTYPE_POWERPC_603ev)
711 return(i);
713 for(i = 0; i < nfat_archs; i++){
714 if(fat_archs64 != NULL){
715 fat_cputype = fat_archs64[i].cputype;
716 fat_cpusubtype = fat_archs64[i].cpusubtype;
718 else{
719 fat_cputype = fat_archs[i].cputype;
720 fat_cpusubtype = fat_archs[i].cpusubtype;
722 if(fat_cputype != cputype)
723 continue;
724 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
725 CPU_SUBTYPE_POWERPC_603e)
726 return(i);
728 for(i = 0; i < nfat_archs; i++){
729 if(fat_archs64 != NULL){
730 fat_cputype = fat_archs64[i].cputype;
731 fat_cpusubtype = fat_archs64[i].cpusubtype;
733 else{
734 fat_cputype = fat_archs[i].cputype;
735 fat_cpusubtype = fat_archs[i].cpusubtype;
737 if(fat_cputype != cputype)
738 continue;
739 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
740 CPU_SUBTYPE_POWERPC_603)
741 return(i);
743 default:
744 for(i = 0; i < nfat_archs; i++){
745 if(fat_archs64 != NULL){
746 fat_cputype = fat_archs64[i].cputype;
747 fat_cpusubtype = fat_archs64[i].cpusubtype;
749 else{
750 fat_cputype = fat_archs[i].cputype;
751 fat_cpusubtype = fat_archs[i].cpusubtype;
753 if(fat_cputype != cputype)
754 continue;
755 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
756 CPU_SUBTYPE_POWERPC_ALL)
757 return(i);
760 break;
761 case CPU_TYPE_POWERPC64:
763 * An exact match as not found. So for all the PowerPC64 subtypes
764 * pick the subtype from the following order starting from a subtype
765 * that will work (contains 64-bit instructions or altivec if
766 * needed):
767 * 970 (currently only the one 64-bit subtype)
768 * For an unknown subtype pick only the ALL type if it exists.
770 switch(cpusubtype & ~CPU_SUBTYPE_MASK){
771 case CPU_SUBTYPE_POWERPC_ALL:
773 * The CPU_SUBTYPE_POWERPC_ALL is only used by the development
774 * environment tools when building a generic ALL type binary.
775 * In the case of a non-exact match we pick the most current
776 * processor.
778 case CPU_SUBTYPE_POWERPC_970:
779 for(i = 0; i < nfat_archs; i++){
780 if(fat_archs64 != NULL){
781 fat_cputype = fat_archs64[i].cputype;
782 fat_cpusubtype = fat_archs64[i].cpusubtype;
784 else{
785 fat_cputype = fat_archs[i].cputype;
786 fat_cpusubtype = fat_archs[i].cpusubtype;
788 if(fat_cputype != cputype)
789 continue;
790 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
791 CPU_SUBTYPE_POWERPC_970)
792 return(i);
794 default:
795 for(i = 0; i < nfat_archs; i++){
796 if(fat_archs64 != NULL){
797 fat_cputype = fat_archs64[i].cputype;
798 fat_cpusubtype = fat_archs64[i].cpusubtype;
800 else{
801 fat_cputype = fat_archs[i].cputype;
802 fat_cpusubtype = fat_archs[i].cpusubtype;
804 if(fat_cputype != cputype)
805 continue;
806 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
807 CPU_SUBTYPE_POWERPC_ALL)
808 return(i);
811 break;
812 case CPU_TYPE_MC88000:
813 for(i = 0; i < nfat_archs; i++){
814 if(fat_archs64 != NULL){
815 fat_cputype = fat_archs64[i].cputype;
816 fat_cpusubtype = fat_archs64[i].cpusubtype;
818 else{
819 fat_cputype = fat_archs[i].cputype;
820 fat_cpusubtype = fat_archs[i].cpusubtype;
822 if(fat_cputype != cputype)
823 continue;
824 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
825 CPU_SUBTYPE_MC88000_ALL)
826 return(i);
828 break;
829 case CPU_TYPE_I860:
830 for(i = 0; i < nfat_archs; i++){
831 if(fat_archs64 != NULL){
832 fat_cputype = fat_archs64[i].cputype;
833 fat_cpusubtype = fat_archs64[i].cpusubtype;
835 else{
836 fat_cputype = fat_archs[i].cputype;
837 fat_cpusubtype = fat_archs[i].cpusubtype;
839 if(fat_cputype != cputype)
840 continue;
841 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
842 CPU_SUBTYPE_I860_ALL)
843 return(i);
845 break;
846 case CPU_TYPE_HPPA:
847 for(i = 0; i < nfat_archs; i++){
848 if(fat_archs64 != NULL){
849 fat_cputype = fat_archs64[i].cputype;
850 fat_cpusubtype = fat_archs64[i].cpusubtype;
852 else{
853 fat_cputype = fat_archs[i].cputype;
854 fat_cpusubtype = fat_archs[i].cpusubtype;
856 if(fat_cputype != cputype)
857 continue;
858 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
859 CPU_SUBTYPE_HPPA_ALL)
860 return(i);
862 break;
863 case CPU_TYPE_SPARC:
864 for(i = 0; i < nfat_archs; i++){
865 if(fat_archs64 != NULL){
866 fat_cputype = fat_archs64[i].cputype;
867 fat_cpusubtype = fat_archs64[i].cpusubtype;
869 else{
870 fat_cputype = fat_archs[i].cputype;
871 fat_cpusubtype = fat_archs[i].cpusubtype;
873 if(fat_cputype != cputype)
874 continue;
875 if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
876 CPU_SUBTYPE_SPARC_ALL)
877 return(i);
879 break;
880 case CPU_TYPE_ARM:
881 case CPU_TYPE_ARM64:
884 * ARM is straightforward, since each architecture is backward
885 * compatible with previous architectures. So, we just take the
886 * highest that is less than our target.
888 int fat_match_found = 0;
889 uint32_t best_fat_arch = 0;
890 for(i = 0; i < nfat_archs; i++){
891 if(fat_archs64 != NULL){
892 fat_cputype = fat_archs64[i].cputype;
893 fat_cpusubtype = fat_archs64[i].cpusubtype;
895 else{
896 fat_cputype = fat_archs[i].cputype;
897 fat_cpusubtype = fat_archs[i].cpusubtype;
899 if(fat_cputype != cputype)
900 continue;
901 if(fat_cpusubtype > cpusubtype)
902 continue;
903 if(!fat_match_found){
904 fat_match_found = 1;
905 best_fat_arch = i;
906 continue;
908 if(fat_archs64 != NULL){
909 if(fat_cpusubtype >
910 fat_archs64[best_fat_arch].cpusubtype)
911 best_fat_arch = i;
913 else{
914 if(fat_cpusubtype >
915 fat_archs[best_fat_arch].cpusubtype)
916 best_fat_arch = i;
919 if(fat_match_found)
920 return(best_fat_arch);
922 * For CPU_TYPE_ARM64, we will fall back to a CPU_TYPE_ARM
923 * with the highest subtype.
925 if(cputype == CPU_TYPE_ARM64){
926 int fat_match_found = 0;
927 uint32_t best_fat_arch = 0;
928 for(i = 0; i < nfat_archs; i++){
929 if(fat_archs64 != NULL){
930 fat_cputype = fat_archs64[i].cputype;
931 fat_cpusubtype = fat_archs64[i].cpusubtype;
933 else{
934 fat_cputype = fat_archs[i].cputype;
935 fat_cpusubtype = fat_archs[i].cpusubtype;
937 if(fat_cputype != CPU_TYPE_ARM)
938 continue;
939 if(!fat_match_found){
940 fat_match_found = 1;
941 best_fat_arch = i;
942 continue;
944 if(fat_archs64 != NULL){
945 if(fat_cpusubtype >
946 fat_archs64[best_fat_arch].cpusubtype)
947 best_fat_arch = i;
949 else{
950 if(fat_cpusubtype >
951 fat_archs[best_fat_arch].cpusubtype)
952 best_fat_arch = i;
955 if(fat_match_found)
956 return(best_fat_arch);
959 break;
960 default:
961 return(-1);
963 return(-1);
967 * NXFindBestFatArch() is passed a cputype and cpusubtype and a set of
968 * fat_arch structs and selects the best one that matches (if any) and returns
969 * a pointer to that fat_arch struct (or NULL). The fat_arch structs must be
970 * in the host byte order and correct such that the fat_archs really points to
971 * enough memory for nfat_arch structs. It is possible that this routine could
972 * fail if new cputypes or cpusubtypes are added and an old version of this
973 * routine is used. But if there is an exact match between the cputype and
974 * cpusubtype and one of the fat_arch structs this routine will always succeed.
976 struct fat_arch *
977 NXFindBestFatArch(
978 cpu_type_t cputype,
979 cpu_subtype_t cpusubtype,
980 struct fat_arch *fat_archs,
981 uint32_t nfat_archs)
983 int32_t i;
985 i = internal_NXFindBestFatArch(cputype, cpusubtype, fat_archs, NULL,
986 nfat_archs);
987 if(i == -1)
988 return(NULL);
989 return(fat_archs + i);
992 /* NXFindBestFatArch_64() is passed a cputype and cpusubtype and a set of
993 * fat_arch_64 structs and selects the best one that matches (if any) and
994 * returns a pointer to that fat_arch_64 struct (or NULL). The fat_arch_64
995 * structs must be in the host byte order and correct such that the fat_archs64
996 * really points to enough memory for nfat_arch structs. It is possible that
997 * this routine could fail if new cputypes or cpusubtypes are added and an old
998 * version of this routine is used. But if there is an exact match between the
999 * cputype and cpusubtype and one of the fat_arch_64 structs this routine will
1000 * always succeed.
1002 struct fat_arch_64 *
1003 NXFindBestFatArch_64(
1004 cpu_type_t cputype,
1005 cpu_subtype_t cpusubtype,
1006 struct fat_arch_64 *fat_archs64,
1007 uint32_t nfat_archs)
1009 int32_t i;
1011 i = internal_NXFindBestFatArch(cputype, cpusubtype, NULL,
1012 fat_archs64, nfat_archs);
1013 if(i == -1)
1014 return(NULL);
1015 return(fat_archs64 + i);
1019 * NXCombineCpuSubtypes() returns the resulting cpusubtype when combining two
1020 * different cpusubtypes for the specified cputype. If the two cpusubtypes
1021 * can't be combined (the specific subtypes are mutually exclusive) -1 is
1022 * returned indicating it is an error to combine them. This can also fail and
1023 * return -1 if new cputypes or cpusubtypes are added and an old version of
1024 * this routine is used. But if the cpusubtypes are the same they can always
1025 * be combined and this routine will return the cpusubtype pass in.
1027 cpu_subtype_t
1028 NXCombineCpuSubtypes(
1029 cpu_type_t cputype,
1030 cpu_subtype_t cpusubtype1,
1031 cpu_subtype_t cpusubtype2)
1034 * If this is an x86_64 cputype and either subtype is the
1035 * "Haswell and compatible" it does not combine with anything else.
1037 if(cputype == CPU_TYPE_X86_64 &&
1038 (cpusubtype1 == CPU_SUBTYPE_X86_64_H ||
1039 cpusubtype2 == CPU_SUBTYPE_X86_64_H))
1040 return((cpu_subtype_t)-1);
1043 * We now combine any i386 or x86-64 subtype to the ALL subtype.
1045 if(cputype == CPU_TYPE_I386)
1046 return(CPU_SUBTYPE_I386_ALL);
1048 if(cputype == CPU_TYPE_X86_64)
1049 return(CPU_SUBTYPE_X86_64_ALL);
1051 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) ==
1052 (cpusubtype2 & ~CPU_SUBTYPE_MASK))
1053 return(cpusubtype1);
1055 switch(cputype){
1056 case CPU_TYPE_MC680x0:
1057 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC680x0_ALL &&
1058 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68030_ONLY &&
1059 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68040)
1060 return((cpu_subtype_t)-1);
1061 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC680x0_ALL &&
1062 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68030_ONLY &&
1063 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68040)
1064 return((cpu_subtype_t)-1);
1066 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY &&
1067 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040)
1068 return((cpu_subtype_t)-1);
1069 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040 &&
1070 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY)
1071 return((cpu_subtype_t)-1);
1073 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY ||
1074 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY)
1075 return(CPU_SUBTYPE_MC68030_ONLY);
1077 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040 ||
1078 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040)
1079 return(CPU_SUBTYPE_MC68040);
1080 break; /* logically can't get here */
1082 case CPU_TYPE_POWERPC:
1084 * Combining with the ALL type becomes the other type. Combining
1085 * anything with the 601 becomes 601. All other non exact matches
1086 * combine to the higher value subtype.
1088 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_ALL)
1089 return(cpusubtype2);
1090 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_ALL)
1091 return(cpusubtype1);
1093 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_601 ||
1094 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_601)
1095 return(CPU_SUBTYPE_POWERPC_601);
1097 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) >
1098 (cpusubtype2 & ~CPU_SUBTYPE_MASK))
1099 return(cpusubtype1);
1100 else
1101 return(cpusubtype2);
1102 break; /* logically can't get here */
1104 case CPU_TYPE_MC88000:
1105 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88000_ALL &&
1106 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88110)
1107 return((cpu_subtype_t)-1);
1108 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88000_ALL &&
1109 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88110)
1110 return((cpu_subtype_t)-1);
1112 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC88110 ||
1113 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC88110)
1114 return(CPU_SUBTYPE_MC88110);
1116 break; /* logically can't get here */
1118 case CPU_TYPE_I860:
1119 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_ALL &&
1120 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_860)
1121 return((cpu_subtype_t)-1);
1122 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_ALL &&
1123 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_860)
1124 return((cpu_subtype_t)-1);
1126 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_I860_860 ||
1127 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_I860_860)
1128 return(CPU_SUBTYPE_I860_860);
1129 break; /* logically can't get here */
1131 case CPU_TYPE_HPPA:
1132 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_ALL &&
1133 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_7100LC)
1134 return((cpu_subtype_t)-1);
1135 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_ALL &&
1136 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_7100LC)
1137 return((cpu_subtype_t)-1);
1139 return(CPU_SUBTYPE_HPPA_7100LC);
1140 break; /* logically can't get here */
1142 case CPU_TYPE_SPARC:
1143 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_SPARC_ALL)
1144 return((cpu_subtype_t)-1);
1145 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_SPARC_ALL)
1146 return((cpu_subtype_t)-1);
1147 break; /* logically can't get here */
1149 case CPU_TYPE_ARM:
1151 * Combinability matrix for ARM:
1152 * V4T V5 XSCALE V6 V7 ALL
1153 * ~~~ ~~ ~~~~~~ ~~ ~~ ~~~
1154 * V4T V4T V5 XSCALE V6 V7 ALL
1155 * V5 V5 V5 -- V6 V7 ALL
1156 * XSCALE XSCALE -- XSCALE -- -- ALL
1157 * V6 V6 V6 -- V6 V7 ALL
1158 * V7 V7 V7 -- V7 V7 ALL
1159 * ALL ALL ALL ALL ALL ALL ALL
1161 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_ALL)
1162 return(cpusubtype2);
1163 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_ALL)
1164 return(cpusubtype1);
1165 switch((cpusubtype1 & ~CPU_SUBTYPE_MASK)){
1166 case CPU_SUBTYPE_ARM_V7:
1167 switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
1168 case CPU_SUBTYPE_ARM_XSCALE:
1169 return((cpu_subtype_t)-1);
1170 default:
1171 return(CPU_SUBTYPE_ARM_V7);
1173 case CPU_SUBTYPE_ARM_V6:
1174 switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
1175 case CPU_SUBTYPE_ARM_XSCALE:
1176 return((cpu_subtype_t)-1);
1177 default:
1178 return(CPU_SUBTYPE_ARM_V6);
1180 case CPU_SUBTYPE_ARM_XSCALE:
1181 switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
1182 case CPU_SUBTYPE_ARM_V7:
1183 case CPU_SUBTYPE_ARM_V6:
1184 case CPU_SUBTYPE_ARM_V5TEJ:
1185 return((cpu_subtype_t)-1);
1186 default:
1187 return(CPU_SUBTYPE_ARM_XSCALE);
1189 case CPU_SUBTYPE_ARM_V5TEJ:
1190 switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
1191 case CPU_SUBTYPE_ARM_XSCALE:
1192 return((cpu_subtype_t)-1);
1193 case CPU_SUBTYPE_ARM_V7:
1194 return(CPU_SUBTYPE_ARM_V7);
1195 case CPU_SUBTYPE_ARM_V6:
1196 return(CPU_SUBTYPE_ARM_V6);
1197 default:
1198 return(CPU_SUBTYPE_ARM_V5TEJ);
1200 case CPU_SUBTYPE_ARM_V4T:
1201 return((cpusubtype2 & ~CPU_SUBTYPE_MASK));
1202 default:
1203 return((cpu_subtype_t)-1);
1206 case CPU_TYPE_ARM64:
1207 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_ARM64_ALL)
1208 return((cpu_subtype_t)-1);
1209 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_ARM64_ALL)
1210 return((cpu_subtype_t)-1);
1211 break; /* logically can't get here */
1213 default:
1214 return((cpu_subtype_t)-1);
1216 return((cpu_subtype_t)-1); /* logically can't get here */
1218 #endif /* !defined(RLD) */