Initial revision
[deliverable/binutils-gdb.git] / bfd / archures.c
CommitLineData
c618de01
SC
1/* BFD library support routines for architectures.
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
3 Hacked by John Gilmore of Cygnus Support.
4a81b561 4
c618de01 5This file is part of BFD, the Binary File Descriptor library.
4a81b561 6
c618de01 7This program is free software; you can redistribute it and/or modify
4a81b561 8it under the terms of the GNU General Public License as published by
c618de01
SC
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
4a81b561 11
c618de01 12This program is distributed in the hope that it will be useful,
4a81b561
DHW
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
c618de01
SC
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21/*doc*
22@section Architectures
23BFD's idea of an architecture is implimented in @code{archures.c}. BFD
6724ff46 24keeps two atoms in a BFD describing the architecture of the data
188d6d22 25attached to the BFD, the @code{enum bfd_architecture arch} field and
c618de01
SC
26the @code{unsigned long machine} field.
27*/
28
29/*proto* bfd_architecture
30This enum gives the object file's CPU
31architecture, in a global sense. E.g. what processor family does it
32belong to? There is another field, which indicates what processor
33within the family is in use. The machine gives a number which
34distingushes different versions of the architecture, containing for
35example 2 and 3 for Intel i960 KA and i960 KB, and 68020 and 68030 for
36Motorola 68020 and 68030.
37
38*+
39enum bfd_architecture
40{
41 bfd_arch_unknown, {* File arch not known *}
42 bfd_arch_obscure, {* Arch known, not one of these *}
43 bfd_arch_m68k, {* Motorola 68xxx *}
44 bfd_arch_vax, {* DEC Vax *}
45 bfd_arch_i960, {* Intel 960 *}
46 {* The order of the following is important.
47 lower number indicates a machine type that
48 only accepts a subset of the instructions
49 available to machines with higher numbers.
50 The exception is the "ca", which is
51 incompatible with all other machines except
52 "core". *}
53
54#define bfd_mach_i960_core 1
55#define bfd_mach_i960_ka_sa 2
56#define bfd_mach_i960_kb_sb 3
57#define bfd_mach_i960_mc 4
58#define bfd_mach_i960_xa 5
59#define bfd_mach_i960_ca 6
60
61 bfd_arch_a29k, {* AMD 29000 *}
62 bfd_arch_sparc, {* SPARC *}
63 bfd_arch_mips, {* MIPS Rxxxx *}
64 bfd_arch_i386, {* Intel 386 *}
65 bfd_arch_ns32k, {* National Semiconductor 32xxx *}
66 bfd_arch_tahoe, {* CCI/Harris Tahoe *}
67 bfd_arch_i860, {* Intel 860 *}
68 bfd_arch_romp, {* IBM ROMP RS/6000 *}
69 bfd_arch_alliant, {* Alliant *}
70 bfd_arch_convex, {* Convex *}
71 bfd_arch_m88k, {* Motorola 88xxx *}
72 bfd_arch_pyramid, {* Pyramid Technology *}
73 bfd_arch_h8_300, {* Hitachi H8/300 *}
74 bfd_arch_last
75 };
76*-
77
78stuff
79
80*/
81
82
4a81b561
DHW
83
84/* $Id$ */
85
c618de01 86#include <sysdep.h>
4a81b561 87#include "bfd.h"
4a81b561
DHW
88
89static char *prt_num_mach ();
90static boolean scan_num_mach ();
91static char *prt_960_mach ();
92static boolean scan_960_mach ();
93
94struct arch_print {
c618de01
SC
95 enum bfd_architecture arch;
96 char *astr;
97 char *(*mach_print)();
98 boolean (*mach_scan)();
4a81b561
DHW
99} arch_print[] = {
100
c618de01
SC
101 {bfd_arch_unknown, "unknown", prt_num_mach, scan_num_mach},
102 {bfd_arch_obscure, "obscure", prt_num_mach, scan_num_mach},
103 {bfd_arch_m68k, "m68k", prt_num_mach, scan_num_mach},
104 {bfd_arch_vax, "vax", prt_num_mach, scan_num_mach},
105 {bfd_arch_i960, "i960", prt_960_mach, scan_960_mach},
106 {bfd_arch_a29k, "a29k", prt_num_mach, scan_num_mach},
107 {bfd_arch_sparc, "sparc", prt_num_mach, scan_num_mach},
108 {bfd_arch_mips, "mips", prt_num_mach, scan_num_mach},
109 {bfd_arch_i386, "i386", prt_num_mach, scan_num_mach},
110 {bfd_arch_ns32k, "ns32k", prt_num_mach, scan_num_mach},
111 {bfd_arch_tahoe, "tahoe", prt_num_mach, scan_num_mach},
112 {bfd_arch_i860, "i860", prt_num_mach, scan_num_mach},
113 {bfd_arch_romp, "romp", prt_num_mach, scan_num_mach},
114 {bfd_arch_alliant, "alliant", prt_num_mach, scan_num_mach},
115 {bfd_arch_convex, "convex", prt_num_mach, scan_num_mach},
116 {bfd_arch_m88k, "m88k", prt_num_mach, scan_num_mach},
117 {bfd_arch_pyramid, "pyramid", prt_num_mach, scan_num_mach},
118 {bfd_arch_h8_300, "H8/300", prt_num_mach, scan_num_mach},
119 {bfd_arch_unknown, (char *)0, prt_num_mach, scan_num_mach},
4a81b561
DHW
120};
121
c618de01
SC
122/*proto* bfd_prinable_arch_mach
123Return a printable string representing the architecture and machine
124type. The result is only good until the next call to
6724ff46 125@code{bfd_printable_arch_mach}.
c618de01
SC
126*; PROTO(CONST char *,bfd_printable_arch_mach,
127 (enum bfd_architecture arch, unsigned long machine));
128*/
129
130CONST char *
131DEFUN(bfd_printable_arch_mach,(arch, machine),
132 enum bfd_architecture arch AND
133 unsigned long machine)
4a81b561
DHW
134{
135 struct arch_print *ap;
136
137 for (ap = arch_print; ap->astr; ap++) {
138 if (ap->arch == arch) {
139 if (machine == 0)
c618de01 140 return ap->astr;
4a81b561
DHW
141 return (*ap->mach_print)(ap, machine);
142 }
143 }
144 return "UNKNOWN!";
145}
146
147static char *
148prt_num_mach (ap, machine)
149 struct arch_print *ap;
150 unsigned long machine;
151{
152 static char result[20];
153
154 sprintf(result, "%s:%ld", ap->astr, (long) machine);
155 return result;
156}
157
c618de01
SC
158/*proto*
159*i bfd_scan_arch_mach
160Scan a string and attempt to turn it into an archive and machine type combination.
161*; PROTO(boolean, bfd_scan_arch_mach,
162 (CONST char *, enum bfd_architecture *, unsigned long *));
163*/
4a81b561
DHW
164
165boolean
4cddd1c9
SC
166DEFUN(bfd_scan_arch_mach,(string, archp, machinep),
167 CONST char *string AND
168 enum bfd_architecture *archp AND
169 unsigned long *machinep)
4a81b561
DHW
170{
171 struct arch_print *ap;
172 int len;
173
174 /* First look for an architecture, possibly followed by machtype. */
175 for (ap = arch_print; ap->astr; ap++) {
176 if (ap->astr[0] != string[0])
177 continue;
178 len = strlen (ap->astr);
179 if (!strncmp (ap->astr, string, len)) {
180 /* We found the architecture, now see about the machine type */
181 if (archp)
c618de01 182 *archp = ap->arch;
4a81b561 183 if (string[len] != '\0') {
c618de01
SC
184 if (ap->mach_scan (string+len, ap, archp, machinep, 1))
185 return true;
4a81b561
DHW
186 }
187 if (machinep)
c618de01 188 *machinep = 0;
4a81b561
DHW
189 return true;
190 }
191 }
192
193 /* Couldn't find an architecture -- try for just a machine type */
194 for (ap = arch_print; ap->astr; ap++) {
195 if (ap->mach_scan (string, ap, archp, machinep, 0))
196 return true;
197 }
198
199 return false;
200}
201
202static boolean
203scan_num_mach (string, ap, archp, machinep, archspec)
204 char *string;
205 struct arch_print *ap;
206 enum bfd_architecture *archp;
207 unsigned long *machinep;
208 int archspec;
209{
210 enum bfd_architecture arch;
211 unsigned long machine;
212 char achar;
213
214 if (archspec) {
215
216 /* Architecture already specified, now go for machine type. */
217 if (string[0] != ':')
218 return false;
219 /* We'll take any valid number that occupies the entire string */
220 if (1 != sscanf (string+1, "%lu%c", &machine, &achar))
221 return false;
222 arch = ap->arch;
223
224 } else {
225
226 /* We couldn't identify an architecture prefix. Perhaps the entire
227 thing is a machine type. Be a lot picker. */
228 if (1 != sscanf (string, "%lu%c", &machine, &achar))
229 return false;
230 switch (machine) {
231 case 68010:
232 case 68020:
233 case 68030:
234 case 68040:
235 case 68332:
c618de01
SC
236 case 68050: arch = bfd_arch_m68k; break;
237 case 68000: arch = bfd_arch_m68k; machine = 0; break;
4a81b561
DHW
238
239 case 80960:
c618de01 240 case 960: arch = bfd_arch_i960; machine = 0; break;
4a81b561
DHW
241
242 case 386:
c618de01
SC
243 case 80386: arch = bfd_arch_i386; machine = 0; break;
244 case 486: arch = bfd_arch_i386; break;
4a81b561 245
c618de01 246 case 29000: arch = bfd_arch_a29k; machine = 0; break;
4a81b561
DHW
247
248 case 32016:
249 case 32032:
250 case 32132:
251 case 32232:
252 case 32332:
253 case 32432:
c618de01
SC
254 case 32532: arch = bfd_arch_ns32k; break;
255 case 32000: arch = bfd_arch_ns32k; machine = 0; break;
4a81b561
DHW
256
257 case 860:
c618de01 258 case 80860: arch = bfd_arch_i860; machine = 0; break;
4a81b561 259
c618de01 260 default: return false;
4a81b561
DHW
261 }
262 }
263
264 if (archp)
265 *archp = arch;
266 if (machinep)
267 *machinep = machine;
268 return true;
269}
270\f
271/* Intel 960 machine variants. */
272
273static char *
274prt_960_mach (ap, machine)
275 struct arch_print *ap;
276 unsigned long machine;
277{
278 static char result[20];
279 char *str;
280
281 switch (machine) {
c618de01
SC
282 case bfd_mach_i960_core: str = "core"; break;
283 case bfd_mach_i960_kb_sb: str = "kb"; break;
284 case bfd_mach_i960_mc: str = "mc"; break;
285 case bfd_mach_i960_xa: str = "xa"; break;
286 case bfd_mach_i960_ca: str = "ca"; break;
287 case bfd_mach_i960_ka_sa: str = "ka"; break;
4a81b561 288 default:
c618de01 289 return prt_num_mach (ap, machine);
4a81b561
DHW
290 }
291 sprintf (result, "%s:%s", ap->astr, str);
292 return result;
293}
294
295static boolean
296scan_960_mach (string, ap, archp, machinep, archspec)
297 char *string;
298 struct arch_print *ap;
299 enum bfd_architecture *archp;
300 unsigned long *machinep;
301 int archspec;
302{
303 unsigned long machine;
304
305 if (!archspec)
306 return false;
307 if (string[0] != ':')
308 return false;
309 string++;
310 if (string[0] == '\0')
311 return false;
312 if (string[0] == 'c' && string[1] == 'o' && string[2] == 'r' &&
313 string[3] == 'e' && string[4] == '\0')
314 machine = bfd_mach_i960_core;
c618de01 315 else if (string[1] == '\0' || string[2] != '\0') /* rest are 2-char */
4a81b561
DHW
316 return false;
317 else if (string[0] == 'k' && string[1] == 'b')
318 machine = bfd_mach_i960_kb_sb;
319 else if (string[0] == 's' && string[1] == 'b')
320 machine = bfd_mach_i960_kb_sb;
321 else if (string[0] == 'm' && string[1] == 'c')
322 machine = bfd_mach_i960_mc;
323 else if (string[0] == 'x' && string[1] == 'a')
324 machine = bfd_mach_i960_xa;
325 else if (string[0] == 'c' && string[1] == 'a')
326 machine = bfd_mach_i960_ca;
327 else if (string[0] == 'k' && string[1] == 'a')
328 machine = bfd_mach_i960_ka_sa;
329 else if (string[0] == 's' && string[1] == 'a')
330 machine = bfd_mach_i960_ka_sa;
331 else
332 return false;
333
334 if (archp)
335 *archp = ap->arch;
336 if (machinep)
337 *machinep = machine;
338 return true;
339}
340
341
342\f
c618de01
SC
343/*proto*
344*i bfd_arch_compatible
345This routine is used to determine whether two BFDs' architectures and machine types are
346compatible. It calculates the lowest common denominator between the
6724ff46 347two architectures and machine types implied by the BFDs and sets the
c618de01
SC
348objects pointed at by @var{archp} and @var{machine} if non NULL.
349
6724ff46 350This routine returns @code{true} if the BFDs are of compatible type,
c618de01
SC
351otherwise @code{false}.
352*; PROTO(boolean, bfd_arch_compatible,
353 (bfd *abfd,
354 bfd *bbfd,
355 enum bfd_architecture *archp,
356 unsigned long *machinep));
357*-*/
4a81b561
DHW
358
359boolean
c618de01
SC
360DEFUN(bfd_arch_compatible,(abfd, bbfd, archp, machinep),
361 bfd *abfd AND
362 bfd *bbfd AND
363 enum bfd_architecture *archp AND
364 unsigned long *machinep)
4a81b561
DHW
365{
366 enum bfd_architecture archa, archb;
367 unsigned long macha, machb;
368 int pick_a;
369
370 archa = bfd_get_architecture (abfd);
371 archb = bfd_get_architecture (bbfd);
372 macha = bfd_get_machine (abfd);
373 machb = bfd_get_machine (bbfd);
374
375 if (archb == bfd_arch_unknown)
c618de01 376 pick_a = 1;
4a81b561 377 else if (archa == bfd_arch_unknown)
c618de01 378 pick_a = 0;
4a81b561 379 else if (archa != archb)
c618de01 380 return false; /* Not compatible */
4a81b561
DHW
381 else {
382 /* Architectures are the same. Check machine types. */
c618de01 383 if (macha == machb) /* Same machine type */
4a81b561 384 pick_a = 1;
c618de01 385 else if (machb == 0) /* B is default */
4a81b561 386 pick_a = 1;
c618de01 387 else if (macha == 0) /* A is default */
4a81b561
DHW
388 pick_a = 0;
389 else switch (archa) {
390 /* If particular machine types of one architecture are not
c618de01
SC
391 compatible with each other, this is the place to put those tests
392 (returning false if incompatible). */
fc723380
JG
393
394 case bfd_arch_i960:
c618de01
SC
395 /* The i960 has two distinct subspecies which may not interbreed:
396 CORE CA
397 CORE KA KB MC
398 Any architecture on the same line is compatible, the one on
399 the right is the least restrictive. */
400 /* So, if either is a ca then the other must be a be core or ca */
401 if (macha == bfd_mach_i960_ca) {
402 if (machb != bfd_mach_i960_ca &&
403 machb != bfd_mach_i960_core) {
404 return false;
405 }
406 pick_a = 1;
407 }
408 else if (machb == bfd_mach_i960_ca) {
409 if (macha != bfd_mach_i960_ca &&
410 macha != bfd_mach_i960_core) {
411 return false;
412 }
413 pick_a = 0;
414 }
415 else {
416 /* This must be from the bottom row, so take the higest */
417 pick_a = (macha > machb);
418 }
419 break;
4a81b561
DHW
420
421 /* For these chips, as far as we care, "lower" numbers are included
c618de01
SC
422 by "higher" numbers, e.g. merge 68010 and 68020 into 68020,
423 386 and 486 into 486, etc. This will need to change
424 if&when we care about things like 68332. */
4a81b561
DHW
425 case bfd_arch_m68k:
426 case bfd_arch_ns32k:
427 case bfd_arch_i386:
428 pick_a = (macha > machb);
429 break;
430
431 /* By default, pick first file's type, for lack of something better. */
432 default:
433 pick_a = 1;
434 }
435 }
436
437 /* Set result based on our pick */
438 if (!pick_a) {
439 archa = archb;
440 macha = machb;
441 }
442 if (archp)
443 *archp = archa;
444 if (machinep)
445 *machinep = macha;
446
447 return true;
448}
c618de01
SC
449
450
451/*proto* bfd_set_arch_mach
452Set atch mach
453*+
454#define bfd_set_arch_mach(abfd, arch, mach) \
455 BFD_SEND (abfd, _bfd_set_arch_mach,\
456 (abfd, arch, mach))
457*-
458*/
459
460
461foo() { }
462
463
464
This page took 0.060029 seconds and 4 git commands to generate.