1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
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.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/*
24 * Copyright (c) 1993 NeXT Computer, Inc.
25 *
26 * Architecture computing functions.
27 *
28 * HISTORY
29 *
30 * 11 April 1997
31 *	Update m98k to ppc and removed the never supported architectures (mips,
32 *	and vax).  Apple Computer, Inc.
33 *
34 * 4 February 1993 Lennart Lovstrand <lennart@next.com>
35 *	Redesigned to use NXArchInfo based names and signatures.
36 *
37 * Originally written at NeXT, Inc.
38 *
39 */
40#ifndef RLD
41#include <stdint.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45#include <limits.h>
46
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>
52
53/* The array of all currently know architecture flags (terminated with an entry
54 * with all zeros).  Pointer to this returned with NXGetAllArchInfos().
55 */
56static 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    {"armv6m", CPU_TYPE_ARM,     CPU_SUBTYPE_ARM_V6M,	   NX_LittleEndian,
138	 "arm v6m"},
139    {"armv7",  CPU_TYPE_ARM,     CPU_SUBTYPE_ARM_V7,	   NX_LittleEndian,
140	 "arm v7"},
141    {"armv7f", CPU_TYPE_ARM,     CPU_SUBTYPE_ARM_V7F,	   NX_LittleEndian,
142	 "arm v7f"},
143    {"armv7s", CPU_TYPE_ARM,     CPU_SUBTYPE_ARM_V7S,	   NX_LittleEndian,
144	 "arm v7s"},
145    {"armv7k", CPU_TYPE_ARM,     CPU_SUBTYPE_ARM_V7K,	   NX_LittleEndian,
146	 "arm v7k"},
147    {"armv7m", CPU_TYPE_ARM,     CPU_SUBTYPE_ARM_V7M,	   NX_LittleEndian,
148	 "arm v7m"},
149    {"armv7em",CPU_TYPE_ARM,     CPU_SUBTYPE_ARM_V7EM,	   NX_LittleEndian,
150	 "arm v7em"},
151    {"little", CPU_TYPE_ANY,     CPU_SUBTYPE_LITTLE_ENDIAN, NX_LittleEndian,
152         "Little Endian"},
153    {"big",    CPU_TYPE_ANY,     CPU_SUBTYPE_BIG_ENDIAN,   NX_BigEndian,
154         "Big Endian"},
155    {"veo1",CPU_TYPE_VEO,	 CPU_SUBTYPE_VEO_1,	   NX_BigEndian,
156	 "veo 1" },
157    {"veo2",CPU_TYPE_VEO,	 CPU_SUBTYPE_VEO_2,	   NX_BigEndian,
158	 "veo 2" },
159    {NULL,     0,		  0,			   0,
160	 NULL}
161};
162
163/*
164 * NXGetAllArchInfos() returns a pointer to an array of all currently know
165 * architecture flags (terminated with an entry with all zeros).
166 */
167const
168NXArchInfo *
169NXGetAllArchInfos(void)
170{
171	return(ArchInfoTable);
172}
173
174/*
175 * NXGetLocalArchInfo() returns the NXArchInfo matching the cputype and
176 * cpusubtype of the local host.  NULL is returned if there is no matching
177 * entry in the ArchInfoTable.
178 */
179const
180NXArchInfo *
181NXGetLocalArchInfo(void)
182{
183    struct host_basic_info hbi;
184    kern_return_t ret;
185    unsigned int count;
186    mach_port_t my_mach_host_self;
187
188	count = HOST_BASIC_INFO_COUNT;
189	my_mach_host_self = mach_host_self();
190	ret = host_info(my_mach_host_self, HOST_BASIC_INFO, (host_info_t)&hbi,
191			&count);
192	mach_port_deallocate(mach_task_self(), my_mach_host_self);
193	if(ret != KERN_SUCCESS)
194	    return(NULL);
195
196	/*
197	 * There is a "bug" in the kernel for compatiblity that on
198	 * an 030 machine host_info() returns cpusubtype
199	 * CPU_SUBTYPE_MC680x0_ALL and not CPU_SUBTYPE_MC68030_ONLY.
200	 */
201	if(hbi.cpu_type == CPU_TYPE_MC680x0 &&
202	   hbi.cpu_subtype == CPU_SUBTYPE_MC680x0_ALL)
203	    hbi.cpu_subtype = CPU_SUBTYPE_MC68030_ONLY;
204
205	return(NXGetArchInfoFromCpuType(hbi.cpu_type, hbi.cpu_subtype));
206}
207
208/*
209 * NXGetArchInfoFromName() is passed an architecture name (like "m68k")
210 * and returns the matching NXArchInfo struct, or NULL if none is found.
211 */
212const
213NXArchInfo *
214NXGetArchInfoFromName(
215const char *name)
216{
217    const NXArchInfo *ai;
218
219	for(ai = ArchInfoTable; ai->name != NULL; ai++)
220	    if(strcmp(ai->name, name) == 0)
221		return(ai);
222
223	return(NULL);
224}
225
226/*
227 * NXGetArchInfoFromName() is passed a cputype and cpusubtype and returns
228 * the matching NXArchInfo struct, or NULL if none is found.  If the
229 * cpusubtype is given as CPU_SUBTYPE_MULTIPLE, the first entry that
230 * matches the given cputype is returned.  This is the NXArchInfo struct
231 * describing the CPU "family".
232 */
233const
234NXArchInfo *
235NXGetArchInfoFromCpuType(
236cpu_type_t cputype,
237cpu_subtype_t cpusubtype)
238{
239    const NXArchInfo *ai;
240    NXArchInfo *q;
241
242    for(ai = ArchInfoTable; ai->name != NULL; ai++)
243	if(ai->cputype == cputype &&
244	   (cpusubtype == CPU_SUBTYPE_MULTIPLE ||
245	    ((ai->cpusubtype & ~CPU_SUBTYPE_MASK) ==
246	     (cpusubtype & ~CPU_SUBTYPE_MASK))))
247	    return(ai);
248
249    if(cputype == CPU_TYPE_I386){
250	q = malloc(sizeof(NXArchInfo));
251	for(ai = ArchInfoTable; ai->name != NULL; ai++){
252	    if(ai->cputype == cputype){
253		*q = *ai;
254		break;
255	    }
256	}
257	q->cpusubtype = cpusubtype;
258	q->description = malloc(sizeof("Intel family  model ") + 2 + 8);
259	if(q->description == NULL)
260	    return(NULL);
261	sprintf((char *)q->description, "Intel family %u model %u",
262		CPU_SUBTYPE_INTEL_FAMILY(cpusubtype & ~CPU_SUBTYPE_MASK),
263		CPU_SUBTYPE_INTEL_MODEL(cpusubtype & ~CPU_SUBTYPE_MASK));
264	return((const NXArchInfo *)q);
265    }
266    else if(cputype == CPU_TYPE_POWERPC){
267	q = malloc(sizeof(NXArchInfo));
268	for(ai = ArchInfoTable; ai->name != NULL; ai++){
269	    if(ai->cputype == cputype){
270		*q = *ai;
271		break;
272	    }
273	}
274	q->cpusubtype = cpusubtype;
275	q->description = malloc(sizeof("PowerPC cpusubtype ") + 10);
276	if(q->description == NULL)
277	    return(NULL);
278	sprintf((char *)q->description, "PowerPC cpusubtype %u", cpusubtype);
279	return((const NXArchInfo *)q);
280    }
281
282    return(NULL);
283}
284
285/*
286 * NXFindBestFatArch() is passed a cputype and cpusubtype and a set of
287 * fat_arch structs and selects the best one that matches (if any) and returns
288 * a pointer to that fat_arch struct (or NULL).  The fat_arch structs must be
289 * in the host byte order and correct such that the fat_archs really points to
290 * enough memory for nfat_arch structs.  It is possible that this routine could
291 * fail if new cputypes or cpusubtypes are added and an old version of this
292 * routine is used.  But if there is an exact match between the cputype and
293 * cpusubtype and one of the fat_arch structs this routine will always succeed.
294 */
295struct fat_arch *
296NXFindBestFatArch(
297cpu_type_t cputype,
298cpu_subtype_t cpusubtype,
299struct fat_arch *fat_archs,
300uint32_t nfat_archs)
301{
302    uint32_t i;
303    int32_t lowest_family, lowest_model, lowest_index;
304
305	/*
306	 * Look for the first exact match.
307	 */
308	for(i = 0; i < nfat_archs; i++){
309	    if(fat_archs[i].cputype == cputype &&
310	       (fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
311		(cpusubtype & ~CPU_SUBTYPE_MASK))
312		return(fat_archs + i);
313	}
314
315	/*
316	 * An exact match was not found so find the next best match which is
317	 * cputype dependent.
318	 */
319	switch(cputype){
320	case CPU_TYPE_I386:
321	    switch(cpusubtype & ~CPU_SUBTYPE_MASK){
322	    default:
323		/*
324		 * Intel cpusubtypes after the pentium (same as 586) are handled
325		 * such that they require an exact match or they can use the
326		 * pentium.  If that is not found call into the loop for the
327		 * earilier subtypes.
328		 */
329		for(i = 0; i < nfat_archs; i++){
330		    if(fat_archs[i].cputype != cputype)
331			continue;
332		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
333			CPU_SUBTYPE_PENT)
334			return(fat_archs + i);
335		}
336	    case CPU_SUBTYPE_PENT:
337	    case CPU_SUBTYPE_486SX:
338		/*
339		 * Since an exact match as not found look for the i486 else
340		 * break into the loop to look for the i386_ALL.
341		 */
342		for(i = 0; i < nfat_archs; i++){
343		    if(fat_archs[i].cputype != cputype)
344			continue;
345		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
346			CPU_SUBTYPE_486)
347			return(fat_archs + i);
348		}
349		break;
350	    case CPU_SUBTYPE_I386_ALL:
351	    /* case CPU_SUBTYPE_I386: same as above */
352	    case CPU_SUBTYPE_486:
353		break;
354	    }
355	    for(i = 0; i < nfat_archs; i++){
356		if(fat_archs[i].cputype != cputype)
357		    continue;
358		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
359		    CPU_SUBTYPE_I386_ALL)
360		    return(fat_archs + i);
361	    }
362
363	    /*
364	     * A match failed, promote as little as possible.
365	     */
366	    for(i = 0; i < nfat_archs; i++){
367		if(fat_archs[i].cputype != cputype)
368		    continue;
369		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
370		   CPU_SUBTYPE_486)
371		    return(fat_archs + i);
372	    }
373	    for(i = 0; i < nfat_archs; i++){
374		if(fat_archs[i].cputype != cputype)
375		    continue;
376		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
377		   CPU_SUBTYPE_486SX)
378		    return(fat_archs + i);
379	    }
380	    for(i = 0; i < nfat_archs; i++){
381		if(fat_archs[i].cputype != cputype)
382		    continue;
383		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
384		   CPU_SUBTYPE_586)
385		    return(fat_archs + i);
386	    }
387	    /*
388	     * Now look for the lowest family and in that the lowest model.
389	     */
390	    lowest_family = CPU_SUBTYPE_INTEL_FAMILY_MAX + 1;
391	    for(i = 0; i < nfat_archs; i++){
392		if(fat_archs[i].cputype != cputype)
393		    continue;
394		if(CPU_SUBTYPE_INTEL_FAMILY(fat_archs[i].cpusubtype &
395					    ~CPU_SUBTYPE_MASK) < lowest_family)
396		    lowest_family = CPU_SUBTYPE_INTEL_FAMILY(
397				fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK);
398	    }
399	    /* if no intel cputypes found return NULL */
400	    if(lowest_family == CPU_SUBTYPE_INTEL_FAMILY_MAX + 1)
401		return(NULL);
402	    lowest_model = INT_MAX;
403	    lowest_index = -1;
404	    for(i = 0; i < nfat_archs; i++){
405		if(fat_archs[i].cputype != cputype)
406		    continue;
407		if(CPU_SUBTYPE_INTEL_FAMILY(fat_archs[i].cpusubtype &
408			~CPU_SUBTYPE_MASK) == lowest_family){
409		    if(CPU_SUBTYPE_INTEL_MODEL(fat_archs[i].cpusubtype &
410			~CPU_SUBTYPE_MASK) < lowest_model){
411		        lowest_model = CPU_SUBTYPE_INTEL_MODEL(
412					fat_archs[i].cpusubtype &
413					~CPU_SUBTYPE_MASK);
414			lowest_index = i;
415		    }
416		}
417	    }
418	    return(fat_archs + lowest_index);
419	case CPU_TYPE_X86_64:
420	    for(i = 0; i < nfat_archs; i++){
421		if(fat_archs[i].cputype != cputype)
422		    continue;
423		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
424		   CPU_SUBTYPE_X86_64_ALL)
425		    return(fat_archs + i);
426	    }
427	    break;
428	case CPU_TYPE_MC680x0:
429	    for(i = 0; i < nfat_archs; i++){
430		if(fat_archs[i].cputype != cputype)
431		    continue;
432		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
433		   CPU_SUBTYPE_MC680x0_ALL)
434		    return(fat_archs + i);
435	    }
436	    /*
437	     * Try to promote if starting from CPU_SUBTYPE_MC680x0_ALL and
438	     * favor the CPU_SUBTYPE_MC68040 over the CPU_SUBTYPE_MC68030_ONLY.
439	     */
440	    if((cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC680x0_ALL){
441		for(i = 0; i < nfat_archs; i++){
442		    if(fat_archs[i].cputype != cputype)
443			continue;
444		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
445		       CPU_SUBTYPE_MC68040)
446			return(fat_archs + i);
447		}
448		for(i = 0; i < nfat_archs; i++){
449		    if(fat_archs[i].cputype != cputype)
450			continue;
451		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
452		       CPU_SUBTYPE_MC68030_ONLY)
453			return(fat_archs + i);
454		}
455	    }
456	    break;
457	case CPU_TYPE_POWERPC:
458	    /*
459	     * An exact match as not found.  So for all the PowerPC subtypes
460	     * pick the subtype from the following order starting from a subtype
461	     * that will work (contains 64-bit instructions or altivec if
462	     * needed):
463	     *	970, 7450, 7400, 750, 604e, 604, 603ev, 603e, 603, ALL
464	     * Note the 601 is NOT in the list above.  It is only picked via
465	     * an exact match.  For an unknown subtype pick only the ALL type if
466	     * it exists.
467	     */
468	    switch(cpusubtype & ~CPU_SUBTYPE_MASK){
469	    case CPU_SUBTYPE_POWERPC_ALL:
470		/*
471		 * The CPU_SUBTYPE_POWERPC_ALL is only used by the development
472		 * environment tools when building a generic ALL type binary.
473		 * In the case of a non-exact match we pick the most current
474		 * processor.
475		 */
476	    case CPU_SUBTYPE_POWERPC_970:
477		for(i = 0; i < nfat_archs; i++){
478		    if(fat_archs[i].cputype != cputype)
479			continue;
480		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
481			CPU_SUBTYPE_POWERPC_970)
482			return(fat_archs + i);
483		}
484	    case CPU_SUBTYPE_POWERPC_7450:
485	    case CPU_SUBTYPE_POWERPC_7400:
486		for(i = 0; i < nfat_archs; i++){
487		    if(fat_archs[i].cputype != cputype)
488			continue;
489		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
490			CPU_SUBTYPE_POWERPC_7450)
491			return(fat_archs + i);
492		}
493		for(i = 0; i < nfat_archs; i++){
494		    if(fat_archs[i].cputype != cputype)
495			continue;
496		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
497			CPU_SUBTYPE_POWERPC_7400)
498			return(fat_archs + i);
499		}
500	    case CPU_SUBTYPE_POWERPC_750:
501	    case CPU_SUBTYPE_POWERPC_604e:
502	    case CPU_SUBTYPE_POWERPC_604:
503	    case CPU_SUBTYPE_POWERPC_603ev:
504	    case CPU_SUBTYPE_POWERPC_603e:
505	    case CPU_SUBTYPE_POWERPC_603:
506		for(i = 0; i < nfat_archs; i++){
507		    if(fat_archs[i].cputype != cputype)
508			continue;
509		    if((fat_archs[i].cpusubtype & CPU_SUBTYPE_MASK) ==
510			CPU_SUBTYPE_POWERPC_750)
511			return(fat_archs + i);
512		}
513		for(i = 0; i < nfat_archs; i++){
514		    if(fat_archs[i].cputype != cputype)
515			continue;
516		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
517			CPU_SUBTYPE_POWERPC_604e)
518			return(fat_archs + i);
519		}
520		for(i = 0; i < nfat_archs; i++){
521		    if(fat_archs[i].cputype != cputype)
522			continue;
523		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
524			CPU_SUBTYPE_POWERPC_604)
525			return(fat_archs + i);
526		}
527		for(i = 0; i < nfat_archs; i++){
528		    if((fat_archs[i].cputype & ~CPU_SUBTYPE_MASK) != cputype)
529			continue;
530		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
531			CPU_SUBTYPE_POWERPC_603ev)
532			return(fat_archs + i);
533		}
534		for(i = 0; i < nfat_archs; i++){
535		    if(fat_archs[i].cputype != cputype)
536			continue;
537		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
538			CPU_SUBTYPE_POWERPC_603e)
539			return(fat_archs + i);
540		}
541		for(i = 0; i < nfat_archs; i++){
542		    if(fat_archs[i].cputype != cputype)
543			continue;
544		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
545			CPU_SUBTYPE_POWERPC_603)
546			return(fat_archs + i);
547		}
548	    default:
549		for(i = 0; i < nfat_archs; i++){
550		    if(fat_archs[i].cputype != cputype)
551			continue;
552		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
553			CPU_SUBTYPE_POWERPC_ALL)
554			return(fat_archs + i);
555		}
556	    }
557	    break;
558	case CPU_TYPE_POWERPC64:
559	    /*
560	     * An exact match as not found.  So for all the PowerPC64 subtypes
561	     * pick the subtype from the following order starting from a subtype
562	     * that will work (contains 64-bit instructions or altivec if
563	     * needed):
564	     *	970 (currently only the one 64-bit subtype)
565	     * For an unknown subtype pick only the ALL type if it exists.
566	     */
567	    switch(cpusubtype & ~CPU_SUBTYPE_MASK){
568	    case CPU_SUBTYPE_POWERPC_ALL:
569		/*
570		 * The CPU_SUBTYPE_POWERPC_ALL is only used by the development
571		 * environment tools when building a generic ALL type binary.
572		 * In the case of a non-exact match we pick the most current
573		 * processor.
574		 */
575	    case CPU_SUBTYPE_POWERPC_970:
576		for(i = 0; i < nfat_archs; i++){
577		    if(fat_archs[i].cputype != cputype)
578			continue;
579		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
580			CPU_SUBTYPE_POWERPC_970)
581			return(fat_archs + i);
582		}
583	    default:
584		for(i = 0; i < nfat_archs; i++){
585		    if(fat_archs[i].cputype != cputype)
586			continue;
587		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
588			CPU_SUBTYPE_POWERPC_ALL)
589			return(fat_archs + i);
590		}
591	    }
592	    break;
593	case CPU_TYPE_MC88000:
594	    for(i = 0; i < nfat_archs; i++){
595		if(fat_archs[i].cputype != cputype)
596		    continue;
597		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
598		   CPU_SUBTYPE_MC88000_ALL)
599		    return(fat_archs + i);
600	    }
601	    break;
602	case CPU_TYPE_I860:
603	    for(i = 0; i < nfat_archs; i++){
604		if(fat_archs[i].cputype != cputype)
605		    continue;
606		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
607		   CPU_SUBTYPE_I860_ALL)
608		    return(fat_archs + i);
609	    }
610	    break;
611	case CPU_TYPE_HPPA:
612	    for(i = 0; i < nfat_archs; i++){
613		if(fat_archs[i].cputype != cputype)
614		    continue;
615		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
616		   CPU_SUBTYPE_HPPA_ALL)
617		    return(fat_archs + i);
618	    }
619	    break;
620	case CPU_TYPE_SPARC:
621	    for(i = 0; i < nfat_archs; i++){
622		if(fat_archs[i].cputype != cputype)
623		    continue;
624		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
625		   CPU_SUBTYPE_SPARC_ALL)
626		    return(fat_archs + i);
627	    }
628	    break;
629	case CPU_TYPE_ARM:
630	    {
631		/*
632		 * ARM is straightforward, since each architecture is backward
633		 * compatible with previous architectures.  So, we just take the
634		 * highest that is less than our target.
635		 */
636		int fat_match_found = 0;
637		uint32_t best_fat_arch = 0;
638		for(i = 0; i < nfat_archs; i++){
639		    if(fat_archs[i].cputype != cputype)
640			continue;
641		    if(fat_archs[i].cpusubtype > cpusubtype)
642			continue;
643		    if(!fat_match_found){
644			fat_match_found = 1;
645			best_fat_arch = i;
646			continue;
647		    }
648		    if(fat_archs[i].cpusubtype >
649		       fat_archs[best_fat_arch].cpusubtype)
650			best_fat_arch = i;
651		}
652		if(fat_match_found)
653		  return fat_archs + best_fat_arch;
654	    }
655	    break;
656	default:
657	    return(NULL);
658	}
659	return(NULL);
660}
661
662/*
663 * NXCombineCpuSubtypes() returns the resulting cpusubtype when combining two
664 * different cpusubtypes for the specified cputype.  If the two cpusubtypes
665 * can't be combined (the specific subtypes are mutually exclusive) -1 is
666 * returned indicating it is an error to combine them.  This can also fail and
667 * return -1 if new cputypes or cpusubtypes are added and an old version of
668 * this routine is used.  But if the cpusubtypes are the same they can always
669 * be combined and this routine will return the cpusubtype pass in.
670 */
671cpu_subtype_t
672NXCombineCpuSubtypes(
673cpu_type_t cputype,
674cpu_subtype_t cpusubtype1,
675cpu_subtype_t cpusubtype2)
676{
677	/*
678	 * We now combine any i386 or x86-64 subtype to the ALL subtype.
679	 */
680	if(cputype == CPU_TYPE_I386)
681	    return(CPU_SUBTYPE_I386_ALL);
682
683	if(cputype == CPU_TYPE_X86_64)
684	    return(CPU_SUBTYPE_X86_64_ALL);
685
686	if((cpusubtype1 & ~CPU_SUBTYPE_MASK) ==
687	   (cpusubtype2 & ~CPU_SUBTYPE_MASK))
688	    return(cpusubtype1);
689
690	switch(cputype){
691	case CPU_TYPE_MC680x0:
692	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC680x0_ALL &&
693	       (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68030_ONLY &&
694	       (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68040)
695		return((cpu_subtype_t)-1);
696	    if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC680x0_ALL &&
697	       (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68030_ONLY &&
698	       (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68040)
699		return((cpu_subtype_t)-1);
700
701	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY &&
702	       (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040)
703		return((cpu_subtype_t)-1);
704	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040 &&
705	       (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY)
706		return((cpu_subtype_t)-1);
707
708	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY ||
709	       (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY)
710		return(CPU_SUBTYPE_MC68030_ONLY);
711
712	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040 ||
713	       (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040)
714		return(CPU_SUBTYPE_MC68040);
715	    break; /* logically can't get here */
716
717	case CPU_TYPE_POWERPC:
718	    /*
719	     * Combining with the ALL type becomes the other type. Combining
720	     * anything with the 601 becomes 601.  All other non exact matches
721	     * combine to the higher value subtype.
722	     */
723	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_ALL)
724		return(cpusubtype2);
725	    if((cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_ALL)
726		return(cpusubtype1);
727
728	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_601 ||
729	       (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_601)
730		return(CPU_SUBTYPE_POWERPC_601);
731
732	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) >
733	       (cpusubtype2 & ~CPU_SUBTYPE_MASK))
734		return(cpusubtype1);
735	    else
736		return(cpusubtype2);
737	    break; /* logically can't get here */
738
739	case CPU_TYPE_MC88000:
740	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88000_ALL &&
741	       (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88110)
742		return((cpu_subtype_t)-1);
743	    if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88000_ALL &&
744	       (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88110)
745		return((cpu_subtype_t)-1);
746
747	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC88110 ||
748	       (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC88110)
749		return(CPU_SUBTYPE_MC88110);
750
751	    break; /* logically can't get here */
752
753	case CPU_TYPE_I860:
754	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_ALL &&
755	       (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_860)
756		return((cpu_subtype_t)-1);
757	    if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_ALL &&
758	       (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_860)
759		return((cpu_subtype_t)-1);
760
761	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_I860_860 ||
762	       (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_I860_860)
763		return(CPU_SUBTYPE_I860_860);
764	    break; /* logically can't get here */
765
766	case CPU_TYPE_HPPA:
767	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_ALL &&
768	       (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_7100LC)
769		return((cpu_subtype_t)-1);
770	    if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_ALL &&
771	       (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_7100LC)
772		return((cpu_subtype_t)-1);
773
774	    return(CPU_SUBTYPE_HPPA_7100LC);
775	    break; /* logically can't get here */
776
777	case CPU_TYPE_SPARC:
778	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_SPARC_ALL)
779			return((cpu_subtype_t)-1);
780	    if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_SPARC_ALL)
781			return((cpu_subtype_t)-1);
782	    break; /* logically can't get here */
783
784	case CPU_TYPE_ARM:
785	    /*
786	     * Combinability matrix for ARM:
787	     *            V4T      V5  XSCALE      V6     V7   ALL
788	     *            ~~~      ~~  ~~~~~~      ~~     ~~   ~~~
789	     * V4T        V4T      V5  XSCALE      V6     V7   ALL
790	     * V5          V5      V5      --      V6     V7   ALL
791	     * XSCALE  XSCALE      --  XSCALE      --     --   ALL
792	     * V6          V6      V6      --      V6     V7   ALL
793	     * V7          V7      V7      --      V7     V7   ALL
794	     * ALL        ALL     ALL     ALL     ALL     ALL  ALL
795	     */
796	    if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_ALL)
797		return(cpusubtype2);
798	    if((cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_ALL)
799		return(cpusubtype1);
800	    switch((cpusubtype1 & ~CPU_SUBTYPE_MASK)){
801		case CPU_SUBTYPE_ARM_V7:
802		    switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
803			case CPU_SUBTYPE_ARM_XSCALE:
804			    return((cpu_subtype_t)-1);
805			default:
806			    return(CPU_SUBTYPE_ARM_V7);
807		    }
808		case CPU_SUBTYPE_ARM_V6:
809		    switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
810			case CPU_SUBTYPE_ARM_XSCALE:
811			    return((cpu_subtype_t)-1);
812			default:
813			    return(CPU_SUBTYPE_ARM_V6);
814		    }
815		case CPU_SUBTYPE_ARM_XSCALE:
816		    switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
817			case CPU_SUBTYPE_ARM_V7:
818			case CPU_SUBTYPE_ARM_V6:
819			case CPU_SUBTYPE_ARM_V5TEJ:
820			    return((cpu_subtype_t)-1);
821			default:
822			    return(CPU_SUBTYPE_ARM_XSCALE);
823		    }
824		case CPU_SUBTYPE_ARM_V5TEJ:
825		    switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
826			case CPU_SUBTYPE_ARM_XSCALE:
827			    return((cpu_subtype_t)-1);
828			case CPU_SUBTYPE_ARM_V7:
829			    return(CPU_SUBTYPE_ARM_V7);
830			case CPU_SUBTYPE_ARM_V6:
831			    return(CPU_SUBTYPE_ARM_V6);
832			default:
833			    return(CPU_SUBTYPE_ARM_V5TEJ);
834		    }
835		case CPU_SUBTYPE_ARM_V4T:
836		    return((cpusubtype2 & ~CPU_SUBTYPE_MASK));
837		default:
838		    return((cpu_subtype_t)-1);
839	    }
840
841	default:
842	    return((cpu_subtype_t)-1);
843	}
844	return((cpu_subtype_t)-1); /* logically can't get here */
845}
846#endif /* !defined(RLD) */
847