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
27static const bfd_arch_info_type *
28bfd_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
34static 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
94const 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.  */
99static 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  */
129static unsigned
130bit_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
142unsigned
143bfd_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
156int 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
187static const bfd_arch_info_type *
188bfd_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