This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / bfd / cpu-m68k.c
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 }