Back to index

cell-binutils  2.17cvs20070401
cpu-m68k.c
Go to the documentation of this file.
00001 /* BFD library support routines for architectures.
00002    Copyright 1990, 1991, 1992, 1993, 1994, 1997, 1998, 2000, 2001, 2002,
00003    2003, 2004, 2006 Free Software Foundation, Inc.
00004    Hacked by Steve Chamberlain of Cygnus Support.
00005 
00006    This file is part of BFD, the Binary File Descriptor library.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00021 
00022 #include "bfd.h"
00023 #include "sysdep.h"
00024 #include "libbfd.h"
00025 #include "opcode/m68k.h"
00026 
00027 static const bfd_arch_info_type *
00028 bfd_m68k_compatible (const bfd_arch_info_type *a,
00029                    const bfd_arch_info_type *b);
00030 
00031 #define N(name, print,d,next)  \
00032 {  32, 32, 8, bfd_arch_m68k, name, "m68k",print,2,d,bfd_m68k_compatible,bfd_default_scan, next, }
00033 
00034 static const bfd_arch_info_type arch_info_struct[] =
00035   {
00036     N(bfd_mach_m68000,  "m68k:68000", FALSE, &arch_info_struct[1]),
00037     N(bfd_mach_m68008,  "m68k:68008", FALSE, &arch_info_struct[2]),
00038     N(bfd_mach_m68010,  "m68k:68010", FALSE, &arch_info_struct[3]),
00039     N(bfd_mach_m68020,  "m68k:68020", FALSE, &arch_info_struct[4]),
00040     N(bfd_mach_m68030,  "m68k:68030", FALSE, &arch_info_struct[5]),
00041     N(bfd_mach_m68040,  "m68k:68040", FALSE, &arch_info_struct[6]),
00042     N(bfd_mach_m68060,  "m68k:68060", FALSE, &arch_info_struct[7]),
00043     N(bfd_mach_cpu32,   "m68k:cpu32", FALSE, &arch_info_struct[8]),
00044     N(bfd_mach_fido,    "m68k:fido",  FALSE, &arch_info_struct[9]),
00045 
00046     /* Various combinations of CF architecture features */
00047     N(bfd_mach_mcf_isa_a_nodiv, "m68k:isa-a:nodiv",
00048       FALSE, &arch_info_struct[10]),
00049     N(bfd_mach_mcf_isa_a, "m68k:isa-a",
00050       FALSE, &arch_info_struct[11]),
00051     N(bfd_mach_mcf_isa_a_mac, "m68k:isa-a:mac",
00052       FALSE, &arch_info_struct[12]),
00053     N(bfd_mach_mcf_isa_a_emac, "m68k:isa-a:emac",
00054       FALSE, &arch_info_struct[13]),
00055     N(bfd_mach_mcf_isa_aplus, "m68k:isa-aplus",
00056       FALSE, &arch_info_struct[14]),
00057     N(bfd_mach_mcf_isa_aplus_mac, "m68k:isa-aplus:mac",
00058       FALSE, &arch_info_struct[15]),
00059     N(bfd_mach_mcf_isa_aplus_emac, "m68k:isa-aplus:emac",
00060       FALSE, &arch_info_struct[16]),
00061     N(bfd_mach_mcf_isa_b_nousp, "m68k:isa-b:nousp",
00062       FALSE, &arch_info_struct[17]),
00063     N(bfd_mach_mcf_isa_b_nousp_mac, "m68k:isa-b:nousp:mac",
00064       FALSE, &arch_info_struct[18]),
00065     N(bfd_mach_mcf_isa_b_nousp_emac, "m68k:isa-b:nousp:emac",
00066       FALSE, &arch_info_struct[19]),
00067     N(bfd_mach_mcf_isa_b, "m68k:isa-b",
00068       FALSE, &arch_info_struct[20]),
00069     N(bfd_mach_mcf_isa_b_mac, "m68k:isa-b:mac",
00070       FALSE, &arch_info_struct[21]),
00071     N(bfd_mach_mcf_isa_b_emac, "m68k:isa-b:emac",
00072       FALSE, &arch_info_struct[22]),
00073     N(bfd_mach_mcf_isa_b_float, "m68k:isa-b:float",
00074       FALSE, &arch_info_struct[23]),
00075     N(bfd_mach_mcf_isa_b_float_mac, "m68k:isa-b:float:mac",
00076       FALSE, &arch_info_struct[24]),
00077     N(bfd_mach_mcf_isa_b_float_emac, "m68k:isa-b:float:emac",
00078       FALSE, &arch_info_struct[25]),
00079 
00080     /* Legacy names for CF architectures */
00081     N(bfd_mach_mcf_isa_a_nodiv, "m68k:5200", FALSE, &arch_info_struct[26]),
00082     N(bfd_mach_mcf_isa_a_mac,"m68k:5206e", FALSE, &arch_info_struct[27]),
00083     N(bfd_mach_mcf_isa_a_mac, "m68k:5307", FALSE, &arch_info_struct[28]),
00084     N(bfd_mach_mcf_isa_b_nousp_mac, "m68k:5407", FALSE, &arch_info_struct[29]),
00085     N(bfd_mach_mcf_isa_aplus_emac, "m68k:528x", FALSE, &arch_info_struct[30]),
00086     N(bfd_mach_mcf_isa_aplus_emac, "m68k:521x", FALSE, &arch_info_struct[31]),
00087     N(bfd_mach_mcf_isa_a_emac, "m68k:5249", FALSE, &arch_info_struct[32]),
00088     N(bfd_mach_mcf_isa_b_float_emac, "m68k:547x",
00089       FALSE, &arch_info_struct[33]),
00090     N(bfd_mach_mcf_isa_b_float_emac, "m68k:548x",
00091       FALSE, &arch_info_struct[34]),
00092     N(bfd_mach_mcf_isa_b_float_emac, "m68k:cfv4e", FALSE, 0),
00093   };
00094 
00095 const bfd_arch_info_type bfd_m68k_arch =
00096   N(0, "m68k", TRUE, &arch_info_struct[0]);
00097 
00098 /* Table indexed by bfd_mach_arch number indicating which
00099    architectural features are supported.  */
00100 static const unsigned m68k_arch_features[] = 
00101 {
00102   0,
00103   m68000|m68881|m68851,
00104   m68000|m68881|m68851,
00105   m68010|m68881|m68851,
00106   m68020|m68881|m68851,
00107   m68030|m68881|m68851,
00108   m68040|m68881|m68851,
00109   m68060|m68881|m68851,
00110   cpu32|m68881,
00111   fido_a|m68881,
00112   mcfisa_a,
00113   mcfisa_a|mcfhwdiv,
00114   mcfisa_a|mcfhwdiv|mcfmac,
00115   mcfisa_a|mcfhwdiv|mcfemac,
00116   mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp,
00117   mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp|mcfmac,
00118   mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp|mcfemac,
00119   mcfisa_a|mcfhwdiv|mcfisa_b,
00120   mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac,
00121   mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac,
00122   mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp,
00123   mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|mcfmac,
00124   mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|mcfemac,
00125   mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat,
00126   mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat|mcfmac,
00127   mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat|mcfemac,
00128 };
00129 
00130 /* Return the count of bits set in MASK  */
00131 static unsigned
00132 bit_count (unsigned mask)
00133 {
00134   unsigned ix;
00135 
00136   for (ix = 0; mask; ix++)
00137     /* Clear the LSB set */
00138     mask ^= mask & -mask;
00139   return ix;
00140 }
00141 
00142 /* Return the architectural features supported by MACH */
00143 
00144 unsigned
00145 bfd_m68k_mach_to_features (int mach)
00146 {
00147   if ((unsigned)mach
00148       >= sizeof (m68k_arch_features) / sizeof (m68k_arch_features[0]))
00149     mach = 0;
00150   return m68k_arch_features[mach];
00151 }
00152 
00153 /* Return the bfd machine that most closely represents the
00154    architectural features.  We find the machine with the smallest
00155    number of additional features.  If there is no such machine, we
00156    find the one with the smallest number of missing features.  */
00157 
00158 int bfd_m68k_features_to_mach (unsigned features)
00159 {
00160   int superset = 0, subset = 0;
00161   unsigned extra = 99, missing = 99;
00162   unsigned ix;
00163 
00164   for (ix = 0;
00165        ix != sizeof (m68k_arch_features) / sizeof (m68k_arch_features[0]);
00166        ix++)
00167     {
00168       unsigned this_extra, this_missing;
00169       
00170       if (m68k_arch_features[ix] == features)
00171        return ix;
00172       this_extra = bit_count (m68k_arch_features[ix] & ~features);
00173       if (this_extra < extra)
00174        {
00175          extra = this_extra;
00176          superset = ix;
00177        }
00178       
00179       this_missing = bit_count (features & ~m68k_arch_features[ix]);
00180       if (this_missing < missing)
00181        {
00182          missing = this_missing;
00183          superset = ix;
00184        }
00185     }
00186   return superset ? superset : subset;
00187 }
00188 
00189 static const bfd_arch_info_type *
00190 bfd_m68k_compatible (const bfd_arch_info_type *a,
00191                    const bfd_arch_info_type *b)
00192 {
00193   if (a->arch != b->arch)
00194     return NULL;
00195 
00196   if (a->bits_per_word != b->bits_per_word)
00197     return NULL;
00198 
00199   if (!a->mach)
00200     return b;
00201   if (!b->mach)
00202     return a;
00203   
00204   if (a->mach <= bfd_mach_m68060 && b->mach <= bfd_mach_m68060)
00205     /* Merge m68k machine. */
00206     return a->mach > b->mach ? a : b;
00207   else if (a->mach >= bfd_mach_cpu32 && b->mach >= bfd_mach_cpu32)
00208     {
00209       /* Merge the machine features.  */
00210       unsigned features = (bfd_m68k_mach_to_features (a->mach)
00211                         | bfd_m68k_mach_to_features (b->mach));
00212 
00213       /* CPU32 and Coldfire are incompatible.  */
00214       if ((~features & (cpu32 | mcfisa_a)) == 0)
00215        return NULL;
00216 
00217       /* Fido and Coldfire are incompatible.  */
00218       if ((~features & (fido_a | mcfisa_a)) == 0)
00219        return NULL;
00220 
00221       /* ISA A+ and ISA B are incompatible.  */
00222       if ((~features & (mcfisa_aa | mcfisa_b)) == 0)
00223        return NULL;
00224 
00225       /* MAC and EMAC code cannot be merged.  */
00226       if ((~features & (mcfmac | mcfemac)) == 0)
00227        return NULL;
00228 
00229       /* CPU32 is compatible with Fido except that Fido does not
00230         support tbl instructions.  Warn when the user wants to mix
00231         the two.  */
00232       if ((a->mach == bfd_mach_cpu32 && b->mach == bfd_mach_fido)
00233          || (a->mach == bfd_mach_fido && b->mach == bfd_mach_cpu32))
00234        {
00235          static int cpu32_fido_mix_warning;
00236          if (!cpu32_fido_mix_warning)
00237            {
00238              cpu32_fido_mix_warning = 1;
00239              (*_bfd_error_handler) ("warning: linking CPU32 objects with fido objects");
00240            }
00241          return bfd_lookup_arch (a->arch,
00242                               bfd_m68k_features_to_mach (fido_a | m68881));
00243        }
00244 
00245       return bfd_lookup_arch (a->arch, bfd_m68k_features_to_mach (features));
00246     }
00247   else
00248     /* They are incompatible.  */
00249     return NULL;
00250 }