836
[darwin-xtools.git] / cctools / libmacho / arch.c
blobf469ad9f5dbbb1078183b9268ab62805fd1d3fe2
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 {"i860", CPU_TYPE_I860, CPU_SUBTYPE_I860_ALL, NX_BigEndian,
65 "Intel 860"},
66 {"m68k", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC680x0_ALL, NX_BigEndian,
67 "Motorola 68K"},
68 {"m88k", CPU_TYPE_MC88000, CPU_SUBTYPE_MC88000_ALL, NX_BigEndian,
69 "Motorola 88K"},
70 {"ppc", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL, NX_BigEndian,
71 "PowerPC"},
72 {"ppc64", CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_ALL, NX_BigEndian,
73 "PowerPC 64-bit"},
74 {"sparc", CPU_TYPE_SPARC, CPU_SUBTYPE_SPARC_ALL, NX_BigEndian,
75 "SPARC"},
76 {"arm", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_ALL, NX_LittleEndian,
77 "ARM"},
78 {"any", CPU_TYPE_ANY, CPU_SUBTYPE_MULTIPLE, NX_UnknownByteOrder,
79 "Architecture Independent"},
80 {"veo", CPU_TYPE_VEO, CPU_SUBTYPE_VEO_ALL, NX_BigEndian,
81 "veo"},
82 /* specific architecture implementations */
83 {"hppa7100LC", CPU_TYPE_HPPA, CPU_SUBTYPE_HPPA_7100LC, NX_BigEndian,
84 "HP-PA 7100LC"},
85 {"m68030", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68030_ONLY, NX_BigEndian,
86 "Motorola 68030"},
87 {"m68040", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68040, NX_BigEndian,
88 "Motorola 68040"},
89 {"i486", CPU_TYPE_I386, CPU_SUBTYPE_486, NX_LittleEndian,
90 "Intel 80486"},
91 {"i486SX", CPU_TYPE_I386, CPU_SUBTYPE_486SX, NX_LittleEndian,
92 "Intel 80486SX"},
93 {"pentium",CPU_TYPE_I386, CPU_SUBTYPE_PENT, NX_LittleEndian,
94 "Intel Pentium"}, /* same as 586 */
95 {"i586", CPU_TYPE_I386, CPU_SUBTYPE_586, NX_LittleEndian,
96 "Intel 80586"},
97 {"pentpro", CPU_TYPE_I386, CPU_SUBTYPE_PENTPRO, NX_LittleEndian,
98 "Intel Pentium Pro"}, /* same as 686 */
99 {"i686", CPU_TYPE_I386, CPU_SUBTYPE_PENTPRO, NX_LittleEndian,
100 "Intel Pentium Pro"},
101 {"pentIIm3", CPU_TYPE_I386, CPU_SUBTYPE_PENTII_M3, NX_LittleEndian,
102 "Intel Pentium II Model 3" },
103 {"pentIIm5", CPU_TYPE_I386, CPU_SUBTYPE_PENTII_M5, NX_LittleEndian,
104 "Intel Pentium II Model 5" },
105 {"pentium4", CPU_TYPE_I386, CPU_SUBTYPE_PENTIUM_4, NX_LittleEndian,
106 "Intel Pentium 4" },
107 {"ppc601", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_601, NX_BigEndian,
108 "PowerPC 601" },
109 {"ppc603", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_603, NX_BigEndian,
110 "PowerPC 603" },
111 {"ppc603e",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_603e, NX_BigEndian,
112 "PowerPC 603e" },
113 {"ppc603ev",CPU_TYPE_POWERPC,CPU_SUBTYPE_POWERPC_603ev,NX_BigEndian,
114 "PowerPC 603ev" },
115 {"ppc604", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_604, NX_BigEndian,
116 "PowerPC 604" },
117 {"ppc604e",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_604e, NX_BigEndian,
118 "PowerPC 604e" },
119 {"ppc750", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_750, NX_BigEndian,
120 "PowerPC 750" },
121 {"ppc7400",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7400, NX_BigEndian,
122 "PowerPC 7400" },
123 {"ppc7450",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7450, NX_BigEndian,
124 "PowerPC 7450" },
125 {"ppc970", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_970, NX_BigEndian,
126 "PowerPC 970" },
127 {"ppc970-64", CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_970, NX_BigEndian,
128 "PowerPC 970 64-bit"},
129 {"armv4t", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V4T, NX_LittleEndian,
130 "arm v4t"},
131 {"armv5", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V5TEJ, NX_LittleEndian,
132 "arm v5"},
133 {"xscale", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_XSCALE, NX_LittleEndian,
134 "arm xscale"},
135 {"armv6", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6, NX_LittleEndian,
136 "arm v6"},
137 {"armv7", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7, NX_LittleEndian,
138 "arm v7"},
139 {"armv7f", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7F, NX_LittleEndian,
140 "arm v7f"},
141 {"armv7s", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S, NX_LittleEndian,
142 "arm v7s"},
143 {"armv7k", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7K, NX_LittleEndian,
144 "arm v7k"},
145 {"little", CPU_TYPE_ANY, CPU_SUBTYPE_LITTLE_ENDIAN, NX_LittleEndian,
146 "Little Endian"},
147 {"big", CPU_TYPE_ANY, CPU_SUBTYPE_BIG_ENDIAN, NX_BigEndian,
148 "Big Endian"},
149 {"veo1",CPU_TYPE_VEO, CPU_SUBTYPE_VEO_1, NX_BigEndian,
150 "veo 1" },
151 {"veo2",CPU_TYPE_VEO, CPU_SUBTYPE_VEO_2, NX_BigEndian,
152 "veo 2" },
153 {NULL, 0, 0, 0,
154 NULL}
158 * NXGetAllArchInfos() returns a pointer to an array of all currently know
159 * architecture flags (terminated with an entry with all zeros).
161 const
162 NXArchInfo *
163 NXGetAllArchInfos(void)
165 return(ArchInfoTable);
169 * NXGetLocalArchInfo() returns the NXArchInfo matching the cputype and
170 * cpusubtype of the local host. NULL is returned if there is no matching
171 * entry in the ArchInfoTable.
173 const
174 NXArchInfo *
175 NXGetLocalArchInfo(void)
177 struct host_basic_info hbi;
178 kern_return_t ret;
179 unsigned int count;
180 mach_port_t my_mach_host_self;
182 count = HOST_BASIC_INFO_COUNT;
183 my_mach_host_self = mach_host_self();
184 ret = host_info(my_mach_host_self, HOST_BASIC_INFO, (host_info_t)&hbi,
185 &count);
186 mach_port_deallocate(mach_task_self(), my_mach_host_self);
187 if(ret != KERN_SUCCESS)
188 return(NULL);
191 * There is a "bug" in the kernel for compatiblity that on
192 * an 030 machine host_info() returns cpusubtype
193 * CPU_SUBTYPE_MC680x0_ALL and not CPU_SUBTYPE_MC68030_ONLY.
195 if(hbi.cpu_type == CPU_TYPE_MC680x0 &&
196 hbi.cpu_subtype == CPU_SUBTYPE_MC680x0_ALL)
197 hbi.cpu_subtype = CPU_SUBTYPE_MC68030_ONLY;
199 return(NXGetArchInfoFromCpuType(hbi.cpu_type, hbi.cpu_subtype));
203 * NXGetArchInfoFromName() is passed an architecture name (like "m68k")
204 * and returns the matching NXArchInfo struct, or NULL if none is found.
206 const
207 NXArchInfo *
208 NXGetArchInfoFromName(
209 const char *name)
211 const NXArchInfo *ai;
213 for(ai = ArchInfoTable; ai->name != NULL; ai++)
214 if(strcmp(ai->name, name) == 0)
215 return(ai);
217 return(NULL);
221 * NXGetArchInfoFromName() is passed a cputype and cpusubtype and returns
222 * the matching NXArchInfo struct, or NULL if none is found. If the
223 * cpusubtype is given as CPU_SUBTYPE_MULTIPLE, the first entry that
224 * matches the given cputype is returned. This is the NXArchInfo struct
225 * describing the CPU "family".
227 const
228 NXArchInfo *
229 NXGetArchInfoFromCpuType(
230 cpu_type_t cputype,
231 cpu_subtype_t cpusubtype)
233 const NXArchInfo *ai;
234 NXArchInfo *q;
236 for(ai = ArchInfoTable; ai->name != NULL; ai++)
237 if(ai->cputype == cputype &&
238 (cpusubtype == CPU_SUBTYPE_MULTIPLE ||
239 ((ai->cpusubtype & ~CPU_SUBTYPE_MASK) ==
240 (cpusubtype & ~CPU_SUBTYPE_MASK))))
241 return(ai);
243 if(cputype == CPU_TYPE_I386){
244 q = malloc(sizeof(NXArchInfo));
245 for(ai = ArchInfoTable; ai->name != NULL; ai++){
246 if(ai->cputype == cputype){
247 *q = *ai;
248 break;
251 q->cpusubtype = cpusubtype;
252 q->description = malloc(sizeof("Intel family model ") + 2 + 8);
253 if(q->description == NULL)
254 return(NULL);
255 sprintf((char *)q->description, "Intel family %u model %u",
256 CPU_SUBTYPE_INTEL_FAMILY(cpusubtype & ~CPU_SUBTYPE_MASK),
257 CPU_SUBTYPE_INTEL_MODEL(cpusubtype & ~CPU_SUBTYPE_MASK));
258 return((const NXArchInfo *)q);
260 else if(cputype == CPU_TYPE_POWERPC){
261 q = malloc(sizeof(NXArchInfo));
262 for(ai = ArchInfoTable; ai->name != NULL; ai++){
263 if(ai->cputype == cputype){
264 *q = *ai;
265 break;
268 q->cpusubtype = cpusubtype;
269 q->description = malloc(sizeof("PowerPC cpusubtype ") + 10);
270 if(q->description == NULL)
271 return(NULL);
272 sprintf((char *)q->description, "PowerPC cpusubtype %u", cpusubtype);
273 return((const NXArchInfo *)q);
276 return(NULL);
280 * NXFindBestFatArch() is passed a cputype and cpusubtype and a set of
281 * fat_arch structs and selects the best one that matches (if any) and returns
282 * a pointer to that fat_arch struct (or NULL). The fat_arch structs must be
283 * in the host byte order and correct such that the fat_archs really points to
284 * enough memory for nfat_arch structs. It is possible that this routine could
285 * fail if new cputypes or cpusubtypes are added and an old version of this
286 * routine is used. But if there is an exact match between the cputype and
287 * cpusubtype and one of the fat_arch structs this routine will always succeed.
289 struct fat_arch *
290 NXFindBestFatArch(
291 cpu_type_t cputype,
292 cpu_subtype_t cpusubtype,
293 struct fat_arch *fat_archs,
294 uint32_t nfat_archs)
296 uint32_t i;
297 int32_t lowest_family, lowest_model, lowest_index;
300 * Look for the first exact match.
302 for(i = 0; i < nfat_archs; i++){
303 if(fat_archs[i].cputype == cputype &&
304 (fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
305 (cpusubtype & ~CPU_SUBTYPE_MASK))
306 return(fat_archs + i);
310 * An exact match was not found so find the next best match which is
311 * cputype dependent.
313 switch(cputype){
314 case CPU_TYPE_I386:
315 switch(cpusubtype & ~CPU_SUBTYPE_MASK){
316 default:
318 * Intel cpusubtypes after the pentium (same as 586) are handled
319 * such that they require an exact match or they can use the
320 * pentium. If that is not found call into the loop for the
321 * earilier subtypes.
323 for(i = 0; i < nfat_archs; i++){
324 if(fat_archs[i].cputype != cputype)
325 continue;
326 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
327 CPU_SUBTYPE_PENT)
328 return(fat_archs + i);
330 case CPU_SUBTYPE_PENT:
331 case CPU_SUBTYPE_486SX:
333 * Since an exact match as not found look for the i486 else
334 * break into the loop to look for the i386_ALL.
336 for(i = 0; i < nfat_archs; i++){
337 if(fat_archs[i].cputype != cputype)
338 continue;
339 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
340 CPU_SUBTYPE_486)
341 return(fat_archs + i);
343 break;
344 case CPU_SUBTYPE_I386_ALL:
345 /* case CPU_SUBTYPE_I386: same as above */
346 case CPU_SUBTYPE_486:
347 break;
349 for(i = 0; i < nfat_archs; i++){
350 if(fat_archs[i].cputype != cputype)
351 continue;
352 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
353 CPU_SUBTYPE_I386_ALL)
354 return(fat_archs + i);
358 * A match failed, promote as little as possible.
360 for(i = 0; i < nfat_archs; i++){
361 if(fat_archs[i].cputype != cputype)
362 continue;
363 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
364 CPU_SUBTYPE_486)
365 return(fat_archs + i);
367 for(i = 0; i < nfat_archs; i++){
368 if(fat_archs[i].cputype != cputype)
369 continue;
370 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
371 CPU_SUBTYPE_486SX)
372 return(fat_archs + i);
374 for(i = 0; i < nfat_archs; i++){
375 if(fat_archs[i].cputype != cputype)
376 continue;
377 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
378 CPU_SUBTYPE_586)
379 return(fat_archs + i);
382 * Now look for the lowest family and in that the lowest model.
384 lowest_family = CPU_SUBTYPE_INTEL_FAMILY_MAX + 1;
385 for(i = 0; i < nfat_archs; i++){
386 if(fat_archs[i].cputype != cputype)
387 continue;
388 if(CPU_SUBTYPE_INTEL_FAMILY(fat_archs[i].cpusubtype &
389 ~CPU_SUBTYPE_MASK) < lowest_family)
390 lowest_family = CPU_SUBTYPE_INTEL_FAMILY(
391 fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK);
393 /* if no intel cputypes found return NULL */
394 if(lowest_family == CPU_SUBTYPE_INTEL_FAMILY_MAX + 1)
395 return(NULL);
396 lowest_model = INT_MAX;
397 lowest_index = -1;
398 for(i = 0; i < nfat_archs; i++){
399 if(fat_archs[i].cputype != cputype)
400 continue;
401 if(CPU_SUBTYPE_INTEL_FAMILY(fat_archs[i].cpusubtype &
402 ~CPU_SUBTYPE_MASK) == lowest_family){
403 if(CPU_SUBTYPE_INTEL_MODEL(fat_archs[i].cpusubtype &
404 ~CPU_SUBTYPE_MASK) < lowest_model){
405 lowest_model = CPU_SUBTYPE_INTEL_MODEL(
406 fat_archs[i].cpusubtype &
407 ~CPU_SUBTYPE_MASK);
408 lowest_index = i;
412 return(fat_archs + lowest_index);
413 case CPU_TYPE_X86_64:
414 for(i = 0; i < nfat_archs; i++){
415 if(fat_archs[i].cputype != cputype)
416 continue;
417 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
418 CPU_SUBTYPE_X86_64_ALL)
419 return(fat_archs + i);
421 break;
422 case CPU_TYPE_MC680x0:
423 for(i = 0; i < nfat_archs; i++){
424 if(fat_archs[i].cputype != cputype)
425 continue;
426 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
427 CPU_SUBTYPE_MC680x0_ALL)
428 return(fat_archs + i);
431 * Try to promote if starting from CPU_SUBTYPE_MC680x0_ALL and
432 * favor the CPU_SUBTYPE_MC68040 over the CPU_SUBTYPE_MC68030_ONLY.
434 if((cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC680x0_ALL){
435 for(i = 0; i < nfat_archs; i++){
436 if(fat_archs[i].cputype != cputype)
437 continue;
438 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
439 CPU_SUBTYPE_MC68040)
440 return(fat_archs + i);
442 for(i = 0; i < nfat_archs; i++){
443 if(fat_archs[i].cputype != cputype)
444 continue;
445 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
446 CPU_SUBTYPE_MC68030_ONLY)
447 return(fat_archs + i);
450 break;
451 case CPU_TYPE_POWERPC:
453 * An exact match as not found. So for all the PowerPC subtypes
454 * pick the subtype from the following order starting from a subtype
455 * that will work (contains 64-bit instructions or altivec if
456 * needed):
457 * 970, 7450, 7400, 750, 604e, 604, 603ev, 603e, 603, ALL
458 * Note the 601 is NOT in the list above. It is only picked via
459 * an exact match. For an unknown subtype pick only the ALL type if
460 * it exists.
462 switch(cpusubtype & ~CPU_SUBTYPE_MASK){
463 case CPU_SUBTYPE_POWERPC_ALL:
465 * The CPU_SUBTYPE_POWERPC_ALL is only used by the development
466 * environment tools when building a generic ALL type binary.
467 * In the case of a non-exact match we pick the most current
468 * processor.
470 case CPU_SUBTYPE_POWERPC_970:
471 for(i = 0; i < nfat_archs; i++){
472 if(fat_archs[i].cputype != cputype)
473 continue;
474 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
475 CPU_SUBTYPE_POWERPC_970)
476 return(fat_archs + i);
478 case CPU_SUBTYPE_POWERPC_7450:
479 case CPU_SUBTYPE_POWERPC_7400:
480 for(i = 0; i < nfat_archs; i++){
481 if(fat_archs[i].cputype != cputype)
482 continue;
483 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
484 CPU_SUBTYPE_POWERPC_7450)
485 return(fat_archs + i);
487 for(i = 0; i < nfat_archs; i++){
488 if(fat_archs[i].cputype != cputype)
489 continue;
490 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
491 CPU_SUBTYPE_POWERPC_7400)
492 return(fat_archs + i);
494 case CPU_SUBTYPE_POWERPC_750:
495 case CPU_SUBTYPE_POWERPC_604e:
496 case CPU_SUBTYPE_POWERPC_604:
497 case CPU_SUBTYPE_POWERPC_603ev:
498 case CPU_SUBTYPE_POWERPC_603e:
499 case CPU_SUBTYPE_POWERPC_603:
500 for(i = 0; i < nfat_archs; i++){
501 if(fat_archs[i].cputype != cputype)
502 continue;
503 if((fat_archs[i].cpusubtype & CPU_SUBTYPE_MASK) ==
504 CPU_SUBTYPE_POWERPC_750)
505 return(fat_archs + i);
507 for(i = 0; i < nfat_archs; i++){
508 if(fat_archs[i].cputype != cputype)
509 continue;
510 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
511 CPU_SUBTYPE_POWERPC_604e)
512 return(fat_archs + i);
514 for(i = 0; i < nfat_archs; i++){
515 if(fat_archs[i].cputype != cputype)
516 continue;
517 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
518 CPU_SUBTYPE_POWERPC_604)
519 return(fat_archs + i);
521 for(i = 0; i < nfat_archs; i++){
522 if((fat_archs[i].cputype & ~CPU_SUBTYPE_MASK) != cputype)
523 continue;
524 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
525 CPU_SUBTYPE_POWERPC_603ev)
526 return(fat_archs + i);
528 for(i = 0; i < nfat_archs; i++){
529 if(fat_archs[i].cputype != cputype)
530 continue;
531 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
532 CPU_SUBTYPE_POWERPC_603e)
533 return(fat_archs + i);
535 for(i = 0; i < nfat_archs; i++){
536 if(fat_archs[i].cputype != cputype)
537 continue;
538 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
539 CPU_SUBTYPE_POWERPC_603)
540 return(fat_archs + i);
542 default:
543 for(i = 0; i < nfat_archs; i++){
544 if(fat_archs[i].cputype != cputype)
545 continue;
546 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
547 CPU_SUBTYPE_POWERPC_ALL)
548 return(fat_archs + i);
551 break;
552 case CPU_TYPE_POWERPC64:
554 * An exact match as not found. So for all the PowerPC64 subtypes
555 * pick the subtype from the following order starting from a subtype
556 * that will work (contains 64-bit instructions or altivec if
557 * needed):
558 * 970 (currently only the one 64-bit subtype)
559 * For an unknown subtype pick only the ALL type if it exists.
561 switch(cpusubtype & ~CPU_SUBTYPE_MASK){
562 case CPU_SUBTYPE_POWERPC_ALL:
564 * The CPU_SUBTYPE_POWERPC_ALL is only used by the development
565 * environment tools when building a generic ALL type binary.
566 * In the case of a non-exact match we pick the most current
567 * processor.
569 case CPU_SUBTYPE_POWERPC_970:
570 for(i = 0; i < nfat_archs; i++){
571 if(fat_archs[i].cputype != cputype)
572 continue;
573 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
574 CPU_SUBTYPE_POWERPC_970)
575 return(fat_archs + i);
577 default:
578 for(i = 0; i < nfat_archs; i++){
579 if(fat_archs[i].cputype != cputype)
580 continue;
581 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
582 CPU_SUBTYPE_POWERPC_ALL)
583 return(fat_archs + i);
586 break;
587 case CPU_TYPE_MC88000:
588 for(i = 0; i < nfat_archs; i++){
589 if(fat_archs[i].cputype != cputype)
590 continue;
591 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
592 CPU_SUBTYPE_MC88000_ALL)
593 return(fat_archs + i);
595 break;
596 case CPU_TYPE_I860:
597 for(i = 0; i < nfat_archs; i++){
598 if(fat_archs[i].cputype != cputype)
599 continue;
600 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
601 CPU_SUBTYPE_I860_ALL)
602 return(fat_archs + i);
604 break;
605 case CPU_TYPE_HPPA:
606 for(i = 0; i < nfat_archs; i++){
607 if(fat_archs[i].cputype != cputype)
608 continue;
609 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
610 CPU_SUBTYPE_HPPA_ALL)
611 return(fat_archs + i);
613 break;
614 case CPU_TYPE_SPARC:
615 for(i = 0; i < nfat_archs; i++){
616 if(fat_archs[i].cputype != cputype)
617 continue;
618 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
619 CPU_SUBTYPE_SPARC_ALL)
620 return(fat_archs + i);
622 break;
623 case CPU_TYPE_ARM:
626 * ARM is straightforward, since each architecture is backward
627 * compatible with previous architectures. So, we just take the
628 * highest that is less than our target.
630 int fat_match_found = 0;
631 uint32_t best_fat_arch = 0;
632 for(i = 0; i < nfat_archs; i++){
633 if(fat_archs[i].cputype != cputype)
634 continue;
635 if(fat_archs[i].cpusubtype > cpusubtype)
636 continue;
637 if(!fat_match_found){
638 fat_match_found = 1;
639 best_fat_arch = i;
640 continue;
642 if(fat_archs[i].cpusubtype >
643 fat_archs[best_fat_arch].cpusubtype)
644 best_fat_arch = i;
646 if(fat_match_found)
647 return fat_archs + best_fat_arch;
649 break;
650 default:
651 return(NULL);
653 return(NULL);
657 * NXCombineCpuSubtypes() returns the resulting cpusubtype when combining two
658 * different cpusubtypes for the specified cputype. If the two cpusubtypes
659 * can't be combined (the specific subtypes are mutually exclusive) -1 is
660 * returned indicating it is an error to combine them. This can also fail and
661 * return -1 if new cputypes or cpusubtypes are added and an old version of
662 * this routine is used. But if the cpusubtypes are the same they can always
663 * be combined and this routine will return the cpusubtype pass in.
665 cpu_subtype_t
666 NXCombineCpuSubtypes(
667 cpu_type_t cputype,
668 cpu_subtype_t cpusubtype1,
669 cpu_subtype_t cpusubtype2)
672 * We now combine any i386 or x86-64 subtype to the ALL subtype.
674 if(cputype == CPU_TYPE_I386)
675 return(CPU_SUBTYPE_I386_ALL);
677 if(cputype == CPU_TYPE_X86_64)
678 return(CPU_SUBTYPE_X86_64_ALL);
680 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) ==
681 (cpusubtype2 & ~CPU_SUBTYPE_MASK))
682 return(cpusubtype1);
684 switch(cputype){
685 case CPU_TYPE_MC680x0:
686 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC680x0_ALL &&
687 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68030_ONLY &&
688 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68040)
689 return((cpu_subtype_t)-1);
690 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC680x0_ALL &&
691 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68030_ONLY &&
692 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68040)
693 return((cpu_subtype_t)-1);
695 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY &&
696 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040)
697 return((cpu_subtype_t)-1);
698 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040 &&
699 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY)
700 return((cpu_subtype_t)-1);
702 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY ||
703 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY)
704 return(CPU_SUBTYPE_MC68030_ONLY);
706 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040 ||
707 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040)
708 return(CPU_SUBTYPE_MC68040);
709 break; /* logically can't get here */
711 case CPU_TYPE_POWERPC:
713 * Combining with the ALL type becomes the other type. Combining
714 * anything with the 601 becomes 601. All other non exact matches
715 * combine to the higher value subtype.
717 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_ALL)
718 return(cpusubtype2);
719 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_ALL)
720 return(cpusubtype1);
722 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_601 ||
723 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_601)
724 return(CPU_SUBTYPE_POWERPC_601);
726 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) >
727 (cpusubtype2 & ~CPU_SUBTYPE_MASK))
728 return(cpusubtype1);
729 else
730 return(cpusubtype2);
731 break; /* logically can't get here */
733 case CPU_TYPE_MC88000:
734 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88000_ALL &&
735 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88110)
736 return((cpu_subtype_t)-1);
737 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88000_ALL &&
738 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88110)
739 return((cpu_subtype_t)-1);
741 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC88110 ||
742 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC88110)
743 return(CPU_SUBTYPE_MC88110);
745 break; /* logically can't get here */
747 case CPU_TYPE_I860:
748 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_ALL &&
749 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_860)
750 return((cpu_subtype_t)-1);
751 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_ALL &&
752 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_860)
753 return((cpu_subtype_t)-1);
755 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_I860_860 ||
756 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_I860_860)
757 return(CPU_SUBTYPE_I860_860);
758 break; /* logically can't get here */
760 case CPU_TYPE_HPPA:
761 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_ALL &&
762 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_7100LC)
763 return((cpu_subtype_t)-1);
764 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_ALL &&
765 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_7100LC)
766 return((cpu_subtype_t)-1);
768 return(CPU_SUBTYPE_HPPA_7100LC);
769 break; /* logically can't get here */
771 case CPU_TYPE_SPARC:
772 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_SPARC_ALL)
773 return((cpu_subtype_t)-1);
774 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_SPARC_ALL)
775 return((cpu_subtype_t)-1);
776 break; /* logically can't get here */
778 case CPU_TYPE_ARM:
780 * Combinability matrix for ARM:
781 * V4T V5 XSCALE V6 V7 ALL
782 * ~~~ ~~ ~~~~~~ ~~ ~~ ~~~
783 * V4T V4T V5 XSCALE V6 V7 ALL
784 * V5 V5 V5 -- V6 V7 ALL
785 * XSCALE XSCALE -- XSCALE -- -- ALL
786 * V6 V6 V6 -- V6 V7 ALL
787 * V7 V7 V7 -- V7 V7 ALL
788 * ALL ALL ALL ALL ALL ALL ALL
790 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_ALL)
791 return(cpusubtype2);
792 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_ALL)
793 return(cpusubtype1);
794 switch((cpusubtype1 & ~CPU_SUBTYPE_MASK)){
795 case CPU_SUBTYPE_ARM_V7:
796 switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
797 case CPU_SUBTYPE_ARM_XSCALE:
798 return((cpu_subtype_t)-1);
799 default:
800 return(CPU_SUBTYPE_ARM_V7);
802 case CPU_SUBTYPE_ARM_V6:
803 switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
804 case CPU_SUBTYPE_ARM_XSCALE:
805 return((cpu_subtype_t)-1);
806 default:
807 return(CPU_SUBTYPE_ARM_V6);
809 case CPU_SUBTYPE_ARM_XSCALE:
810 switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
811 case CPU_SUBTYPE_ARM_V7:
812 case CPU_SUBTYPE_ARM_V6:
813 case CPU_SUBTYPE_ARM_V5TEJ:
814 return((cpu_subtype_t)-1);
815 default:
816 return(CPU_SUBTYPE_ARM_XSCALE);
818 case CPU_SUBTYPE_ARM_V5TEJ:
819 switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
820 case CPU_SUBTYPE_ARM_XSCALE:
821 return((cpu_subtype_t)-1);
822 case CPU_SUBTYPE_ARM_V7:
823 return(CPU_SUBTYPE_ARM_V7);
824 case CPU_SUBTYPE_ARM_V6:
825 return(CPU_SUBTYPE_ARM_V6);
826 default:
827 return(CPU_SUBTYPE_ARM_V5TEJ);
829 case CPU_SUBTYPE_ARM_V4T:
830 return((cpusubtype2 & ~CPU_SUBTYPE_MASK));
831 default:
832 return((cpu_subtype_t)-1);
835 default:
836 return((cpu_subtype_t)-1);
838 return((cpu_subtype_t)-1); /* logically can't get here */
840 #endif /* !defined(RLD) */