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