(root)/
binutils-2.41/
bfd/
cpu-sh.c
       1  /* BFD library support routines for the Renesas / SuperH SH architecture.
       2     Copyright (C) 1993-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 "../opcodes/sh-opc.h"
      26  
      27  
      28  #define N(NUMBER, PRINT, DEFAULT, NEXT)			\
      29    {							\
      30      32,     /* Bits in a word.  */			\
      31      32,     /* Bits in an address.  */			\
      32      8,	    /* Bits in a byte.  */			\
      33      bfd_arch_sh,					\
      34      NUMBER,						\
      35      "sh",						\
      36      PRINT,						\
      37      1,		/* Section alignment power.  */		\
      38      DEFAULT,						\
      39      bfd_default_compatible,				\
      40      bfd_default_scan,					\
      41      bfd_arch_default_fill,				\
      42      NEXT,						\
      43      0 /* Maximum offset of a reloc from the start of an insn.  */ \
      44    }
      45  
      46  static const bfd_arch_info_type arch_info_struct[] =
      47  {
      48    N (bfd_mach_sh2,          "sh2",       false, arch_info_struct + 1),
      49    N (bfd_mach_sh2e,         "sh2e",      false, arch_info_struct + 2),
      50    N (bfd_mach_sh_dsp,       "sh-dsp",    false, arch_info_struct + 3),
      51    N (bfd_mach_sh3,          "sh3",       false, arch_info_struct + 4),
      52    N (bfd_mach_sh3_nommu,    "sh3-nommu", false, arch_info_struct + 5),
      53    N (bfd_mach_sh3_dsp,      "sh3-dsp",   false, arch_info_struct + 6),
      54    N (bfd_mach_sh3e,         "sh3e",      false, arch_info_struct + 7),
      55    N (bfd_mach_sh4,          "sh4",       false, arch_info_struct + 8),
      56    N (bfd_mach_sh4a,         "sh4a",      false, arch_info_struct + 9),
      57    N (bfd_mach_sh4al_dsp,    "sh4al-dsp", false, arch_info_struct + 10),
      58    N (bfd_mach_sh4_nofpu,    "sh4-nofpu", false, arch_info_struct + 11),
      59    N (bfd_mach_sh4_nommu_nofpu, "sh4-nommu-nofpu", false, arch_info_struct + 12),
      60    N (bfd_mach_sh4a_nofpu,   "sh4a-nofpu", false, arch_info_struct + 13),
      61    N (bfd_mach_sh2a,         "sh2a",       false, arch_info_struct + 14),
      62    N (bfd_mach_sh2a_nofpu,   "sh2a-nofpu", false, arch_info_struct + 15),
      63    N (bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu, "sh2a-nofpu-or-sh4-nommu-nofpu", false, arch_info_struct + 16),
      64    N (bfd_mach_sh2a_nofpu_or_sh3_nommu, "sh2a-nofpu-or-sh3-nommu", false, arch_info_struct + 17),
      65    N (bfd_mach_sh2a_or_sh4,  "sh2a-or-sh4",  false, arch_info_struct + 18),
      66    N (bfd_mach_sh2a_or_sh3e, "sh2a-or-sh3e", false, NULL)
      67  };
      68  
      69  const bfd_arch_info_type bfd_sh_arch =
      70    N (bfd_mach_sh, "sh", true, arch_info_struct + 0);
      71  
      72  /* This table defines the mappings from the BFD internal numbering
      73     system to the opcodes internal flags system.
      74     It is used by the functions defined below.
      75     The prototypes for these SH specific functions are found in
      76     sh-opc.h .  */
      77  
      78  static struct { unsigned long bfd_mach, arch, arch_up; } bfd_to_arch_table[] =
      79  {
      80    { bfd_mach_sh,	      arch_sh1,		    arch_sh_up },
      81    { bfd_mach_sh2,	      arch_sh2,		    arch_sh2_up },
      82    { bfd_mach_sh2e,	      arch_sh2e,	    arch_sh2e_up },
      83    { bfd_mach_sh_dsp,	      arch_sh_dsp,	    arch_sh_dsp_up },
      84    { bfd_mach_sh2a,	      arch_sh2a,	    arch_sh2a_up },
      85    { bfd_mach_sh2a_nofpu,      arch_sh2a_nofpu,	    arch_sh2a_nofpu_up },
      86  
      87    { bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu,	    arch_sh2a_nofpu_or_sh4_nommu_nofpu,	  arch_sh2a_nofpu_or_sh4_nommu_nofpu_up },
      88    { bfd_mach_sh2a_nofpu_or_sh3_nommu,		    arch_sh2a_nofpu_or_sh3_nommu,	  arch_sh2a_nofpu_or_sh3_nommu_up },
      89    { bfd_mach_sh2a_or_sh4,     arch_sh2a_or_sh4,	    arch_sh2a_or_sh4_up },
      90    { bfd_mach_sh2a_or_sh3e,    arch_sh2a_or_sh3e,    arch_sh2a_or_sh3e_up },
      91  
      92    { bfd_mach_sh3,	      arch_sh3,		    arch_sh3_up },
      93    { bfd_mach_sh3_nommu,	      arch_sh3_nommu,	    arch_sh3_nommu_up },
      94    { bfd_mach_sh3_dsp,	      arch_sh3_dsp,	    arch_sh3_dsp_up },
      95    { bfd_mach_sh3e,	      arch_sh3e,	    arch_sh3e_up },
      96    { bfd_mach_sh4,	      arch_sh4,		    arch_sh4_up },
      97    { bfd_mach_sh4a,	      arch_sh4a,	    arch_sh4a_up },
      98    { bfd_mach_sh4al_dsp,	      arch_sh4al_dsp,	    arch_sh4al_dsp_up },
      99    { bfd_mach_sh4_nofpu,	      arch_sh4_nofpu,	    arch_sh4_nofpu_up },
     100    { bfd_mach_sh4_nommu_nofpu, arch_sh4_nommu_nofpu, arch_sh4_nommu_nofpu_up },
     101    { bfd_mach_sh4a_nofpu,      arch_sh4a_nofpu,	    arch_sh4a_nofpu_up },
     102    { 0, 0, 0 }	/* Terminator.  */
     103  };
     104  
     105  
     106  /* Convert a BFD mach number into the right opcodes arch flags
     107     using the table above.  */
     108  
     109  unsigned int
     110  sh_get_arch_from_bfd_mach (unsigned long mach)
     111  {
     112    int i = 0;
     113  
     114    while (bfd_to_arch_table[i].bfd_mach != 0)
     115      if (bfd_to_arch_table[i].bfd_mach == mach)
     116        return bfd_to_arch_table[i].arch;
     117      else
     118        i++;
     119  
     120    return SH_ARCH_UNKNOWN_ARCH;
     121  }
     122  
     123  
     124  /* Convert a BFD mach number into a set of opcodes arch flags
     125     describing all the compatible architectures (i.e. arch_up)
     126     using the table above.  */
     127  
     128  unsigned int
     129  sh_get_arch_up_from_bfd_mach (unsigned long mach)
     130  {
     131    int i = 0;
     132  
     133    while (bfd_to_arch_table[i].bfd_mach != 0)
     134      if (bfd_to_arch_table[i].bfd_mach == mach)
     135        return bfd_to_arch_table[i].arch_up;
     136      else
     137        i++;
     138  
     139    return SH_ARCH_UNKNOWN_ARCH;
     140  }
     141  
     142  
     143  /* Convert an arbitary arch_set - not necessarily corresponding
     144     directly to anything in the table above - to the most generic
     145     architecture which supports all the required features, and
     146     return the corresponding BFD mach.  */
     147  
     148  unsigned long
     149  sh_get_bfd_mach_from_arch_set (unsigned int arch_set)
     150  {
     151    unsigned long result = 0;
     152    unsigned int best = ~arch_set;
     153    unsigned int co_mask = ~0;
     154    int i = 0;
     155  
     156    /* If arch_set permits variants with no coprocessor then do not allow
     157       the other irrelevant co-processor bits to influence the choice:
     158         e.g. if dsp is disallowed by arch_set, then the algorithm would
     159         prefer fpu variants over nofpu variants because they also disallow
     160         dsp - even though the nofpu would be the most correct choice.
     161       This assumes that EVERY fpu/dsp variant has a no-coprocessor
     162       counter-part, or their non-fpu/dsp instructions do not have the
     163       no co-processor bit set.  */
     164    if (arch_set & arch_sh_no_co)
     165      co_mask = ~(arch_sh_sp_fpu | arch_sh_dp_fpu | arch_sh_has_dsp);
     166  
     167    while (bfd_to_arch_table[i].bfd_mach != 0)
     168      {
     169        unsigned int try = bfd_to_arch_table[i].arch_up & co_mask;
     170  
     171        /* Conceptually: Find the architecture with the least number
     172  	 of extra features or, if they have the same number, then
     173  	 the greatest number of required features.  Disregard
     174  	 architectures where the required features alone do
     175  	 not describe a valid architecture.  */
     176        if (((try & ~arch_set) < (best & ~arch_set)
     177  	   || ((try & ~arch_set) == (best & ~arch_set)
     178  	       && (~try & arch_set) < (~best & arch_set)))
     179  	  && SH_MERGE_ARCH_SET_VALID (try, arch_set))
     180  	{
     181  	  result = bfd_to_arch_table[i].bfd_mach;
     182  	  best = try;
     183  	}
     184  
     185        i++;
     186      }
     187  
     188    /* This might happen if a new variant is added to sh-opc.h
     189       but no corresponding entry is added to the table above.  */
     190    BFD_ASSERT (result != 0);
     191  
     192    return result;
     193  }