1 /* BFD library support routines for architectures.
2    Copyright 1990, 1991, 1992, 1993, 1994, 1997, 1998, 2000, 2001, 2002,
3    2003, 2004, 2006 Free Software Foundation, Inc.
4    Hacked by Steve Chamberlain of Cygnus Support.
5 
6    This file is part of BFD, the Binary File Descriptor library.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
21 
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
25 #include "opcode/m68k.h"
26 
27 static const bfd_arch_info_type *
28 bfd_m68k_compatible (const bfd_arch_info_type *a,
29 		     const bfd_arch_info_type *b);
30 
31 #define N(name, print,d,next)  \
32 {  32, 32, 8, bfd_arch_m68k, name, "m68k",print,2,d,bfd_m68k_compatible,bfd_default_scan, next, }
33 
34 static const bfd_arch_info_type arch_info_struct[] =
35   {
36     N(bfd_mach_m68000,  "m68k:68000", FALSE, &arch_info_struct[1]),
37     N(bfd_mach_m68008,  "m68k:68008", FALSE, &arch_info_struct[2]),
38     N(bfd_mach_m68010,  "m68k:68010", FALSE, &arch_info_struct[3]),
39     N(bfd_mach_m68020,  "m68k:68020", FALSE, &arch_info_struct[4]),
40     N(bfd_mach_m68030,  "m68k:68030", FALSE, &arch_info_struct[5]),
41     N(bfd_mach_m68040,  "m68k:68040", FALSE, &arch_info_struct[6]),
42     N(bfd_mach_m68060,  "m68k:68060", FALSE, &arch_info_struct[7]),
43     N(bfd_mach_cpu32,   "m68k:cpu32", FALSE, &arch_info_struct[8]),
44 
45     /* Various combinations of CF architecture features */
46     N(bfd_mach_mcf_isa_a_nodiv, "m68k:isa-a:nodiv",
47       FALSE, &arch_info_struct[9]),
48     N(bfd_mach_mcf_isa_a, "m68k:isa-a",
49       FALSE, &arch_info_struct[10]),
50     N(bfd_mach_mcf_isa_a_mac, "m68k:isa-a:mac",
51       FALSE, &arch_info_struct[11]),
52     N(bfd_mach_mcf_isa_a_emac, "m68k:isa-a:emac",
53       FALSE, &arch_info_struct[12]),
54     N(bfd_mach_mcf_isa_aplus, "m68k:isa-aplus",
55       FALSE, &arch_info_struct[13]),
56     N(bfd_mach_mcf_isa_aplus_mac, "m68k:isa-aplus:mac",
57       FALSE, &arch_info_struct[14]),
58     N(bfd_mach_mcf_isa_aplus_emac, "m68k:isa-aplus:emac",
59       FALSE, &arch_info_struct[15]),
60     N(bfd_mach_mcf_isa_b_nousp, "m68k:isa-b:nousp",
61       FALSE, &arch_info_struct[16]),
62     N(bfd_mach_mcf_isa_b_nousp_mac, "m68k:isa-b:nousp:mac",
63       FALSE, &arch_info_struct[17]),
64     N(bfd_mach_mcf_isa_b_nousp_emac, "m68k:isa-b:nousp:emac",
65       FALSE, &arch_info_struct[18]),
66     N(bfd_mach_mcf_isa_b, "m68k:isa-b",
67       FALSE, &arch_info_struct[19]),
68     N(bfd_mach_mcf_isa_b_mac, "m68k:isa-b:mac",
69       FALSE, &arch_info_struct[20]),
70     N(bfd_mach_mcf_isa_b_emac, "m68k:isa-b:emac",
71       FALSE, &arch_info_struct[21]),
72     N(bfd_mach_mcf_isa_b_float, "m68k:isa-b:float",
73       FALSE, &arch_info_struct[22]),
74     N(bfd_mach_mcf_isa_b_float_mac, "m68k:isa-b:float:mac",
75       FALSE, &arch_info_struct[23]),
76     N(bfd_mach_mcf_isa_b_float_emac, "m68k:isa-b:float:emac",
77       FALSE, &arch_info_struct[24]),
78 
79     /* Legacy names for CF architectures */
80     N(bfd_mach_mcf_isa_a_nodiv, "m68k:5200", FALSE, &arch_info_struct[25]),
81     N(bfd_mach_mcf_isa_a_mac,"m68k:5206e", FALSE, &arch_info_struct[26]),
82     N(bfd_mach_mcf_isa_a_mac, "m68k:5307", FALSE, &arch_info_struct[27]),
83     N(bfd_mach_mcf_isa_b_nousp_mac, "m68k:5407", FALSE, &arch_info_struct[28]),
84     N(bfd_mach_mcf_isa_aplus_emac, "m68k:528x", FALSE, &arch_info_struct[29]),
85     N(bfd_mach_mcf_isa_aplus_emac, "m68k:521x", FALSE, &arch_info_struct[30]),
86     N(bfd_mach_mcf_isa_a_emac, "m68k:5249", FALSE, &arch_info_struct[31]),
87     N(bfd_mach_mcf_isa_b_float_emac, "m68k:547x",
88       FALSE, &arch_info_struct[32]),
89     N(bfd_mach_mcf_isa_b_float_emac, "m68k:548x",
90       FALSE, &arch_info_struct[33]),
91     N(bfd_mach_mcf_isa_b_float_emac, "m68k:cfv4e", FALSE, 0),
92   };
93 
94 const bfd_arch_info_type bfd_m68k_arch =
95   N(0, "m68k", TRUE, &arch_info_struct[0]);
96 
97 /* Table indexed by bfd_mach_arch number indicating which
98    architectural features are supported.  */
99 static const unsigned m68k_arch_features[] =
100 {
101   0,
102   m68000|m68881|m68851,
103   m68000|m68881|m68851,
104   m68010|m68881|m68851,
105   m68020|m68881|m68851,
106   m68030|m68881|m68851,
107   m68040|m68881|m68851,
108   m68060|m68881|m68851,
109   cpu32|m68881,
110   mcfisa_a,
111   mcfisa_a|mcfhwdiv,
112   mcfisa_a|mcfhwdiv|mcfmac,
113   mcfisa_a|mcfhwdiv|mcfemac,
114   mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp,
115   mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp|mcfmac,
116   mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp|mcfemac,
117   mcfisa_a|mcfhwdiv|mcfisa_b,
118   mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac,
119   mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac,
120   mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp,
121   mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|mcfmac,
122   mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|mcfemac,
123   mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat,
124   mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat|mcfmac,
125   mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat|mcfemac,
126 };
127 
128 /* Return the count of bits set in MASK  */
129 static unsigned
130 bit_count (unsigned mask)
131 {
132   unsigned ix;
133 
134   for (ix = 0; mask; ix++)
135     /* Clear the LSB set */
136     mask ^= mask & -mask;
137   return ix;
138 }
139 
140 /* Return the architectural features supported by MACH */
141 
142 unsigned
143 bfd_m68k_mach_to_features (int mach)
144 {
145   if ((unsigned)mach
146       >= sizeof (m68k_arch_features) / sizeof (m68k_arch_features[0]))
147     mach = 0;
148   return m68k_arch_features[mach];
149 }
150 
151 /* Return the bfd machine that most closely represents the
152    architectural features.  We find the machine with the smallest
153    number of additional features.  If there is no such machine, we
154    find the one with the smallest number of missing features.  */
155 
156 int bfd_m68k_features_to_mach (unsigned features)
157 {
158   int superset = 0, subset = 0;
159   unsigned extra = 99, missing = 99;
160   unsigned ix;
161 
162   for (ix = 0;
163        ix != sizeof (m68k_arch_features) / sizeof (m68k_arch_features[0]);
164        ix++)
165     {
166       unsigned this_extra, this_missing;
167 
168       if (m68k_arch_features[ix] == features)
169 	return ix;
170       this_extra = bit_count (m68k_arch_features[ix] & ~features);
171       if (this_extra < extra)
172 	{
173 	  extra = this_extra;
174 	  superset = ix;
175 	}
176 
177       this_missing = bit_count (features & ~m68k_arch_features[ix]);
178       if (this_missing < missing)
179 	{
180 	  missing = this_missing;
181 	  superset = ix;
182 	}
183     }
184   return superset ? superset : subset;
185 }
186 
187 static const bfd_arch_info_type *
188 bfd_m68k_compatible (const bfd_arch_info_type *a,
189 		     const bfd_arch_info_type *b)
190 {
191   if (a->arch != b->arch)
192     return NULL;
193 
194   if (a->bits_per_word != b->bits_per_word)
195     return NULL;
196 
197   if (!a->mach)
198     return b;
199   if (!b->mach)
200     return a;
201 
202   if (a->mach <= bfd_mach_m68060 && b->mach <= bfd_mach_m68060)
203     /* Merge m68k machine. */
204     return a->mach > b->mach ? a : b;
205   else if (a->mach >= bfd_mach_mcf_isa_a_nodiv
206 	   && b->mach >= bfd_mach_mcf_isa_a_nodiv)
207     {
208       /* Merge cf machine.  */
209       unsigned features = (bfd_m68k_mach_to_features (a->mach)
210 			   | bfd_m68k_mach_to_features (b->mach));
211 
212       /* ISA A+ and ISA B are incompatible.  */
213       if ((~features & (mcfisa_aa | mcfisa_b)) == 0)
214 	return NULL;
215 
216       /* MAC and EMAC code cannot be merged.  */
217       if ((~features & (mcfmac | mcfemac)) == 0)
218 	return NULL;
219 
220       return bfd_lookup_arch (a->arch, bfd_m68k_features_to_mach (features));
221     }
222   else
223     /* They are incompatible.  */
224     return NULL;
225 }
226