xref: /netbsd-src/external/gpl3/binutils/dist/bfd/cpu-sh.c (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
12a6b7db3Sskrll /* BFD library support routines for the Renesas / SuperH SH architecture.
2*cb63e24eSchristos    Copyright (C) 1993-2024 Free Software Foundation, Inc.
32a6b7db3Sskrll    Hacked by Steve Chamberlain of Cygnus Support.
42a6b7db3Sskrll 
52a6b7db3Sskrll    This file is part of BFD, the Binary File Descriptor library.
62a6b7db3Sskrll 
72a6b7db3Sskrll    This program is free software; you can redistribute it and/or modify
82a6b7db3Sskrll    it under the terms of the GNU General Public License as published by
92a6b7db3Sskrll    the Free Software Foundation; either version 3 of the License, or
102a6b7db3Sskrll    (at your option) any later version.
112a6b7db3Sskrll 
122a6b7db3Sskrll    This program is distributed in the hope that it will be useful,
132a6b7db3Sskrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
142a6b7db3Sskrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
152a6b7db3Sskrll    GNU General Public License for more details.
162a6b7db3Sskrll 
172a6b7db3Sskrll    You should have received a copy of the GNU General Public License
182a6b7db3Sskrll    along with this program; if not, write to the Free Software
192a6b7db3Sskrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
202a6b7db3Sskrll    MA 02110-1301, USA.  */
212a6b7db3Sskrll 
222a6b7db3Sskrll #include "sysdep.h"
232a6b7db3Sskrll #include "bfd.h"
242a6b7db3Sskrll #include "libbfd.h"
252a6b7db3Sskrll #include "../opcodes/sh-opc.h"
262a6b7db3Sskrll 
276f4ced0bSchristos 
286f4ced0bSchristos #define N(NUMBER, PRINT, DEFAULT, NEXT)			\
296f4ced0bSchristos   {							\
306f4ced0bSchristos     32,     /* Bits in a word.  */			\
316f4ced0bSchristos     32,     /* Bits in an address.  */			\
326f4ced0bSchristos     8,	    /* Bits in a byte.  */			\
336f4ced0bSchristos     bfd_arch_sh,					\
346f4ced0bSchristos     NUMBER,						\
356f4ced0bSchristos     "sh",						\
366f4ced0bSchristos     PRINT,						\
376f4ced0bSchristos     1,		/* Section alignment power.  */		\
386f4ced0bSchristos     DEFAULT,						\
396f4ced0bSchristos     bfd_default_compatible,				\
406f4ced0bSchristos     bfd_default_scan,					\
416f4ced0bSchristos     bfd_arch_default_fill,				\
426f4ced0bSchristos     NEXT,						\
436f4ced0bSchristos     0 /* Maximum offset of a reloc from the start of an insn.  */ \
446f4ced0bSchristos   }
452a6b7db3Sskrll 
462a6b7db3Sskrll static const bfd_arch_info_type arch_info_struct[] =
472a6b7db3Sskrll {
484f645668Schristos   N (bfd_mach_sh2,          "sh2",       false, arch_info_struct + 1),
494f645668Schristos   N (bfd_mach_sh2e,         "sh2e",      false, arch_info_struct + 2),
504f645668Schristos   N (bfd_mach_sh_dsp,       "sh-dsp",    false, arch_info_struct + 3),
514f645668Schristos   N (bfd_mach_sh3,          "sh3",       false, arch_info_struct + 4),
524f645668Schristos   N (bfd_mach_sh3_nommu,    "sh3-nommu", false, arch_info_struct + 5),
534f645668Schristos   N (bfd_mach_sh3_dsp,      "sh3-dsp",   false, arch_info_struct + 6),
544f645668Schristos   N (bfd_mach_sh3e,         "sh3e",      false, arch_info_struct + 7),
554f645668Schristos   N (bfd_mach_sh4,          "sh4",       false, arch_info_struct + 8),
564f645668Schristos   N (bfd_mach_sh4a,         "sh4a",      false, arch_info_struct + 9),
574f645668Schristos   N (bfd_mach_sh4al_dsp,    "sh4al-dsp", false, arch_info_struct + 10),
584f645668Schristos   N (bfd_mach_sh4_nofpu,    "sh4-nofpu", false, arch_info_struct + 11),
594f645668Schristos   N (bfd_mach_sh4_nommu_nofpu, "sh4-nommu-nofpu", false, arch_info_struct + 12),
604f645668Schristos   N (bfd_mach_sh4a_nofpu,   "sh4a-nofpu", false, arch_info_struct + 13),
614f645668Schristos   N (bfd_mach_sh2a,         "sh2a",       false, arch_info_struct + 14),
624f645668Schristos   N (bfd_mach_sh2a_nofpu,   "sh2a-nofpu", false, arch_info_struct + 15),
634f645668Schristos   N (bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu, "sh2a-nofpu-or-sh4-nommu-nofpu", false, arch_info_struct + 16),
644f645668Schristos   N (bfd_mach_sh2a_nofpu_or_sh3_nommu, "sh2a-nofpu-or-sh3-nommu", false, arch_info_struct + 17),
654f645668Schristos   N (bfd_mach_sh2a_or_sh4,  "sh2a-or-sh4",  false, arch_info_struct + 18),
664f645668Schristos   N (bfd_mach_sh2a_or_sh3e, "sh2a-or-sh3e", false, NULL)
672a6b7db3Sskrll };
682a6b7db3Sskrll 
692a6b7db3Sskrll const bfd_arch_info_type bfd_sh_arch =
704f645668Schristos   N (bfd_mach_sh, "sh", true, arch_info_struct + 0);
712a6b7db3Sskrll 
722a6b7db3Sskrll /* This table defines the mappings from the BFD internal numbering
732a6b7db3Sskrll    system to the opcodes internal flags system.
742a6b7db3Sskrll    It is used by the functions defined below.
752a6b7db3Sskrll    The prototypes for these SH specific functions are found in
762a6b7db3Sskrll    sh-opc.h .  */
772a6b7db3Sskrll 
782a6b7db3Sskrll static struct { unsigned long bfd_mach, arch, arch_up; } bfd_to_arch_table[] =
792a6b7db3Sskrll {
802a6b7db3Sskrll   { bfd_mach_sh,	      arch_sh1,		    arch_sh_up },
812a6b7db3Sskrll   { bfd_mach_sh2,	      arch_sh2,		    arch_sh2_up },
822a6b7db3Sskrll   { bfd_mach_sh2e,	      arch_sh2e,	    arch_sh2e_up },
832a6b7db3Sskrll   { bfd_mach_sh_dsp,	      arch_sh_dsp,	    arch_sh_dsp_up },
842a6b7db3Sskrll   { bfd_mach_sh2a,	      arch_sh2a,	    arch_sh2a_up },
852a6b7db3Sskrll   { bfd_mach_sh2a_nofpu,      arch_sh2a_nofpu,	    arch_sh2a_nofpu_up },
862a6b7db3Sskrll 
872a6b7db3Sskrll   { bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu,	    arch_sh2a_nofpu_or_sh4_nommu_nofpu,	  arch_sh2a_nofpu_or_sh4_nommu_nofpu_up },
882a6b7db3Sskrll   { bfd_mach_sh2a_nofpu_or_sh3_nommu,		    arch_sh2a_nofpu_or_sh3_nommu,	  arch_sh2a_nofpu_or_sh3_nommu_up },
892a6b7db3Sskrll   { bfd_mach_sh2a_or_sh4,     arch_sh2a_or_sh4,	    arch_sh2a_or_sh4_up },
902a6b7db3Sskrll   { bfd_mach_sh2a_or_sh3e,    arch_sh2a_or_sh3e,    arch_sh2a_or_sh3e_up },
912a6b7db3Sskrll 
922a6b7db3Sskrll   { bfd_mach_sh3,	      arch_sh3,		    arch_sh3_up },
932a6b7db3Sskrll   { bfd_mach_sh3_nommu,	      arch_sh3_nommu,	    arch_sh3_nommu_up },
942a6b7db3Sskrll   { bfd_mach_sh3_dsp,	      arch_sh3_dsp,	    arch_sh3_dsp_up },
952a6b7db3Sskrll   { bfd_mach_sh3e,	      arch_sh3e,	    arch_sh3e_up },
962a6b7db3Sskrll   { bfd_mach_sh4,	      arch_sh4,		    arch_sh4_up },
972a6b7db3Sskrll   { bfd_mach_sh4a,	      arch_sh4a,	    arch_sh4a_up },
982a6b7db3Sskrll   { bfd_mach_sh4al_dsp,	      arch_sh4al_dsp,	    arch_sh4al_dsp_up },
992a6b7db3Sskrll   { bfd_mach_sh4_nofpu,	      arch_sh4_nofpu,	    arch_sh4_nofpu_up },
1002a6b7db3Sskrll   { bfd_mach_sh4_nommu_nofpu, arch_sh4_nommu_nofpu, arch_sh4_nommu_nofpu_up },
1012a6b7db3Sskrll   { bfd_mach_sh4a_nofpu,      arch_sh4a_nofpu,	    arch_sh4a_nofpu_up },
1022a6b7db3Sskrll   { 0, 0, 0 }	/* Terminator.  */
1032a6b7db3Sskrll };
1042a6b7db3Sskrll 
1052a6b7db3Sskrll 
1062a6b7db3Sskrll /* Convert a BFD mach number into the right opcodes arch flags
1072a6b7db3Sskrll    using the table above.  */
1082a6b7db3Sskrll 
1092a6b7db3Sskrll unsigned int
sh_get_arch_from_bfd_mach(unsigned long mach)1102a6b7db3Sskrll sh_get_arch_from_bfd_mach (unsigned long mach)
1112a6b7db3Sskrll {
1122a6b7db3Sskrll   int i = 0;
1132a6b7db3Sskrll 
1142a6b7db3Sskrll   while (bfd_to_arch_table[i].bfd_mach != 0)
1152a6b7db3Sskrll     if (bfd_to_arch_table[i].bfd_mach == mach)
1162a6b7db3Sskrll       return bfd_to_arch_table[i].arch;
1172a6b7db3Sskrll     else
1182a6b7db3Sskrll       i++;
1192a6b7db3Sskrll 
1202a6b7db3Sskrll   return SH_ARCH_UNKNOWN_ARCH;
1212a6b7db3Sskrll }
1222a6b7db3Sskrll 
1232a6b7db3Sskrll 
1242a6b7db3Sskrll /* Convert a BFD mach number into a set of opcodes arch flags
1252a6b7db3Sskrll    describing all the compatible architectures (i.e. arch_up)
1262a6b7db3Sskrll    using the table above.  */
1272a6b7db3Sskrll 
1282a6b7db3Sskrll unsigned int
sh_get_arch_up_from_bfd_mach(unsigned long mach)1292a6b7db3Sskrll sh_get_arch_up_from_bfd_mach (unsigned long mach)
1302a6b7db3Sskrll {
1312a6b7db3Sskrll   int i = 0;
1322a6b7db3Sskrll 
1332a6b7db3Sskrll   while (bfd_to_arch_table[i].bfd_mach != 0)
1342a6b7db3Sskrll     if (bfd_to_arch_table[i].bfd_mach == mach)
1352a6b7db3Sskrll       return bfd_to_arch_table[i].arch_up;
1362a6b7db3Sskrll     else
1372a6b7db3Sskrll       i++;
1382a6b7db3Sskrll 
1392a6b7db3Sskrll   return SH_ARCH_UNKNOWN_ARCH;
1402a6b7db3Sskrll }
1412a6b7db3Sskrll 
1422a6b7db3Sskrll 
1432a6b7db3Sskrll /* Convert an arbitary arch_set - not necessarily corresponding
1442a6b7db3Sskrll    directly to anything in the table above - to the most generic
1452a6b7db3Sskrll    architecture which supports all the required features, and
1462a6b7db3Sskrll    return the corresponding BFD mach.  */
1472a6b7db3Sskrll 
1482a6b7db3Sskrll unsigned long
sh_get_bfd_mach_from_arch_set(unsigned int arch_set)1492a6b7db3Sskrll sh_get_bfd_mach_from_arch_set (unsigned int arch_set)
1502a6b7db3Sskrll {
1512a6b7db3Sskrll   unsigned long result = 0;
1522a6b7db3Sskrll   unsigned int best = ~arch_set;
1532a6b7db3Sskrll   unsigned int co_mask = ~0;
1542a6b7db3Sskrll   int i = 0;
1552a6b7db3Sskrll 
1562a6b7db3Sskrll   /* If arch_set permits variants with no coprocessor then do not allow
1572a6b7db3Sskrll      the other irrelevant co-processor bits to influence the choice:
1582a6b7db3Sskrll        e.g. if dsp is disallowed by arch_set, then the algorithm would
1592a6b7db3Sskrll        prefer fpu variants over nofpu variants because they also disallow
1602a6b7db3Sskrll        dsp - even though the nofpu would be the most correct choice.
1612a6b7db3Sskrll      This assumes that EVERY fpu/dsp variant has a no-coprocessor
1622a6b7db3Sskrll      counter-part, or their non-fpu/dsp instructions do not have the
1632a6b7db3Sskrll      no co-processor bit set.  */
1642a6b7db3Sskrll   if (arch_set & arch_sh_no_co)
1652a6b7db3Sskrll     co_mask = ~(arch_sh_sp_fpu | arch_sh_dp_fpu | arch_sh_has_dsp);
1662a6b7db3Sskrll 
1672a6b7db3Sskrll   while (bfd_to_arch_table[i].bfd_mach != 0)
1682a6b7db3Sskrll     {
1692a6b7db3Sskrll       unsigned int try = bfd_to_arch_table[i].arch_up & co_mask;
1702a6b7db3Sskrll 
1712a6b7db3Sskrll       /* Conceptually: Find the architecture with the least number
1722a6b7db3Sskrll 	 of extra features or, if they have the same number, then
1732a6b7db3Sskrll 	 the greatest number of required features.  Disregard
1742a6b7db3Sskrll 	 architectures where the required features alone do
1752a6b7db3Sskrll 	 not describe a valid architecture.  */
1762a6b7db3Sskrll       if (((try & ~arch_set) < (best & ~arch_set)
1772a6b7db3Sskrll 	   || ((try & ~arch_set) == (best & ~arch_set)
1782a6b7db3Sskrll 	       && (~try & arch_set) < (~best & arch_set)))
1792a6b7db3Sskrll 	  && SH_MERGE_ARCH_SET_VALID (try, arch_set))
1802a6b7db3Sskrll 	{
1812a6b7db3Sskrll 	  result = bfd_to_arch_table[i].bfd_mach;
1822a6b7db3Sskrll 	  best = try;
1832a6b7db3Sskrll 	}
1842a6b7db3Sskrll 
1852a6b7db3Sskrll       i++;
1862a6b7db3Sskrll     }
1872a6b7db3Sskrll 
1882a6b7db3Sskrll   /* This might happen if a new variant is added to sh-opc.h
1892a6b7db3Sskrll      but no corresponding entry is added to the table above.  */
1902a6b7db3Sskrll   BFD_ASSERT (result != 0);
1912a6b7db3Sskrll 
1922a6b7db3Sskrll   return result;
1932a6b7db3Sskrll }
194