175fd0b74Schristos /* BFD library support routines for the Renesas / SuperH SH architecture.
2*e992f068Schristos Copyright (C) 1993-2022 Free Software Foundation, Inc.
375fd0b74Schristos Hacked by Steve Chamberlain of Cygnus Support.
475fd0b74Schristos
575fd0b74Schristos This file is part of BFD, the Binary File Descriptor library.
675fd0b74Schristos
775fd0b74Schristos This program is free software; you can redistribute it and/or modify
875fd0b74Schristos it under the terms of the GNU General Public License as published by
975fd0b74Schristos the Free Software Foundation; either version 3 of the License, or
1075fd0b74Schristos (at your option) any later version.
1175fd0b74Schristos
1275fd0b74Schristos This program is distributed in the hope that it will be useful,
1375fd0b74Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1475fd0b74Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1575fd0b74Schristos GNU General Public License for more details.
1675fd0b74Schristos
1775fd0b74Schristos You should have received a copy of the GNU General Public License
1875fd0b74Schristos along with this program; if not, write to the Free Software
1975fd0b74Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
2075fd0b74Schristos MA 02110-1301, USA. */
2175fd0b74Schristos
2275fd0b74Schristos #include "sysdep.h"
2375fd0b74Schristos #include "bfd.h"
2475fd0b74Schristos #include "libbfd.h"
2575fd0b74Schristos #include "../opcodes/sh-opc.h"
2675fd0b74Schristos
27012573ebSchristos
28012573ebSchristos #define N(NUMBER, PRINT, DEFAULT, NEXT) \
29012573ebSchristos { \
30012573ebSchristos 32, /* Bits in a word. */ \
31012573ebSchristos 32, /* Bits in an address. */ \
32012573ebSchristos 8, /* Bits in a byte. */ \
33012573ebSchristos bfd_arch_sh, \
34012573ebSchristos NUMBER, \
35012573ebSchristos "sh", \
36012573ebSchristos PRINT, \
37012573ebSchristos 1, /* Section alignment power. */ \
38012573ebSchristos DEFAULT, \
39012573ebSchristos bfd_default_compatible, \
40012573ebSchristos bfd_default_scan, \
41012573ebSchristos bfd_arch_default_fill, \
42012573ebSchristos NEXT, \
43012573ebSchristos 0 /* Maximum offset of a reloc from the start of an insn. */ \
44012573ebSchristos }
4575fd0b74Schristos
4675fd0b74Schristos static const bfd_arch_info_type arch_info_struct[] =
4775fd0b74Schristos {
48*e992f068Schristos N (bfd_mach_sh2, "sh2", false, arch_info_struct + 1),
49*e992f068Schristos N (bfd_mach_sh2e, "sh2e", false, arch_info_struct + 2),
50*e992f068Schristos N (bfd_mach_sh_dsp, "sh-dsp", false, arch_info_struct + 3),
51*e992f068Schristos N (bfd_mach_sh3, "sh3", false, arch_info_struct + 4),
52*e992f068Schristos N (bfd_mach_sh3_nommu, "sh3-nommu", false, arch_info_struct + 5),
53*e992f068Schristos N (bfd_mach_sh3_dsp, "sh3-dsp", false, arch_info_struct + 6),
54*e992f068Schristos N (bfd_mach_sh3e, "sh3e", false, arch_info_struct + 7),
55*e992f068Schristos N (bfd_mach_sh4, "sh4", false, arch_info_struct + 8),
56*e992f068Schristos N (bfd_mach_sh4a, "sh4a", false, arch_info_struct + 9),
57*e992f068Schristos N (bfd_mach_sh4al_dsp, "sh4al-dsp", false, arch_info_struct + 10),
58*e992f068Schristos N (bfd_mach_sh4_nofpu, "sh4-nofpu", false, arch_info_struct + 11),
59*e992f068Schristos N (bfd_mach_sh4_nommu_nofpu, "sh4-nommu-nofpu", false, arch_info_struct + 12),
60*e992f068Schristos N (bfd_mach_sh4a_nofpu, "sh4a-nofpu", false, arch_info_struct + 13),
61*e992f068Schristos N (bfd_mach_sh2a, "sh2a", false, arch_info_struct + 14),
62*e992f068Schristos N (bfd_mach_sh2a_nofpu, "sh2a-nofpu", false, arch_info_struct + 15),
63*e992f068Schristos N (bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu, "sh2a-nofpu-or-sh4-nommu-nofpu", false, arch_info_struct + 16),
64*e992f068Schristos N (bfd_mach_sh2a_nofpu_or_sh3_nommu, "sh2a-nofpu-or-sh3-nommu", false, arch_info_struct + 17),
65*e992f068Schristos N (bfd_mach_sh2a_or_sh4, "sh2a-or-sh4", false, arch_info_struct + 18),
66*e992f068Schristos N (bfd_mach_sh2a_or_sh3e, "sh2a-or-sh3e", false, NULL)
6775fd0b74Schristos };
6875fd0b74Schristos
6975fd0b74Schristos const bfd_arch_info_type bfd_sh_arch =
70*e992f068Schristos N (bfd_mach_sh, "sh", true, arch_info_struct + 0);
7175fd0b74Schristos
7275fd0b74Schristos /* This table defines the mappings from the BFD internal numbering
7375fd0b74Schristos system to the opcodes internal flags system.
7475fd0b74Schristos It is used by the functions defined below.
7575fd0b74Schristos The prototypes for these SH specific functions are found in
7675fd0b74Schristos sh-opc.h . */
7775fd0b74Schristos
7875fd0b74Schristos static struct { unsigned long bfd_mach, arch, arch_up; } bfd_to_arch_table[] =
7975fd0b74Schristos {
8075fd0b74Schristos { bfd_mach_sh, arch_sh1, arch_sh_up },
8175fd0b74Schristos { bfd_mach_sh2, arch_sh2, arch_sh2_up },
8275fd0b74Schristos { bfd_mach_sh2e, arch_sh2e, arch_sh2e_up },
8375fd0b74Schristos { bfd_mach_sh_dsp, arch_sh_dsp, arch_sh_dsp_up },
8475fd0b74Schristos { bfd_mach_sh2a, arch_sh2a, arch_sh2a_up },
8575fd0b74Schristos { bfd_mach_sh2a_nofpu, arch_sh2a_nofpu, arch_sh2a_nofpu_up },
8675fd0b74Schristos
8775fd0b74Schristos { bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu, arch_sh2a_nofpu_or_sh4_nommu_nofpu, arch_sh2a_nofpu_or_sh4_nommu_nofpu_up },
8875fd0b74Schristos { bfd_mach_sh2a_nofpu_or_sh3_nommu, arch_sh2a_nofpu_or_sh3_nommu, arch_sh2a_nofpu_or_sh3_nommu_up },
8975fd0b74Schristos { bfd_mach_sh2a_or_sh4, arch_sh2a_or_sh4, arch_sh2a_or_sh4_up },
9075fd0b74Schristos { bfd_mach_sh2a_or_sh3e, arch_sh2a_or_sh3e, arch_sh2a_or_sh3e_up },
9175fd0b74Schristos
9275fd0b74Schristos { bfd_mach_sh3, arch_sh3, arch_sh3_up },
9375fd0b74Schristos { bfd_mach_sh3_nommu, arch_sh3_nommu, arch_sh3_nommu_up },
9475fd0b74Schristos { bfd_mach_sh3_dsp, arch_sh3_dsp, arch_sh3_dsp_up },
9575fd0b74Schristos { bfd_mach_sh3e, arch_sh3e, arch_sh3e_up },
9675fd0b74Schristos { bfd_mach_sh4, arch_sh4, arch_sh4_up },
9775fd0b74Schristos { bfd_mach_sh4a, arch_sh4a, arch_sh4a_up },
9875fd0b74Schristos { bfd_mach_sh4al_dsp, arch_sh4al_dsp, arch_sh4al_dsp_up },
9975fd0b74Schristos { bfd_mach_sh4_nofpu, arch_sh4_nofpu, arch_sh4_nofpu_up },
10075fd0b74Schristos { bfd_mach_sh4_nommu_nofpu, arch_sh4_nommu_nofpu, arch_sh4_nommu_nofpu_up },
10175fd0b74Schristos { bfd_mach_sh4a_nofpu, arch_sh4a_nofpu, arch_sh4a_nofpu_up },
10275fd0b74Schristos { 0, 0, 0 } /* Terminator. */
10375fd0b74Schristos };
10475fd0b74Schristos
10575fd0b74Schristos
10675fd0b74Schristos /* Convert a BFD mach number into the right opcodes arch flags
10775fd0b74Schristos using the table above. */
10875fd0b74Schristos
10975fd0b74Schristos unsigned int
sh_get_arch_from_bfd_mach(unsigned long mach)11075fd0b74Schristos sh_get_arch_from_bfd_mach (unsigned long mach)
11175fd0b74Schristos {
11275fd0b74Schristos int i = 0;
11375fd0b74Schristos
11475fd0b74Schristos while (bfd_to_arch_table[i].bfd_mach != 0)
11575fd0b74Schristos if (bfd_to_arch_table[i].bfd_mach == mach)
11675fd0b74Schristos return bfd_to_arch_table[i].arch;
11775fd0b74Schristos else
11875fd0b74Schristos i++;
11975fd0b74Schristos
12075fd0b74Schristos /* Machine not found. */
12175fd0b74Schristos BFD_FAIL();
12275fd0b74Schristos
12375fd0b74Schristos return SH_ARCH_UNKNOWN_ARCH;
12475fd0b74Schristos }
12575fd0b74Schristos
12675fd0b74Schristos
12775fd0b74Schristos /* Convert a BFD mach number into a set of opcodes arch flags
12875fd0b74Schristos describing all the compatible architectures (i.e. arch_up)
12975fd0b74Schristos using the table above. */
13075fd0b74Schristos
13175fd0b74Schristos unsigned int
sh_get_arch_up_from_bfd_mach(unsigned long mach)13275fd0b74Schristos sh_get_arch_up_from_bfd_mach (unsigned long mach)
13375fd0b74Schristos {
13475fd0b74Schristos int i = 0;
13575fd0b74Schristos
13675fd0b74Schristos while (bfd_to_arch_table[i].bfd_mach != 0)
13775fd0b74Schristos if (bfd_to_arch_table[i].bfd_mach == mach)
13875fd0b74Schristos return bfd_to_arch_table[i].arch_up;
13975fd0b74Schristos else
14075fd0b74Schristos i++;
14175fd0b74Schristos
14275fd0b74Schristos /* Machine not found. */
14375fd0b74Schristos BFD_FAIL();
14475fd0b74Schristos
14575fd0b74Schristos return SH_ARCH_UNKNOWN_ARCH;
14675fd0b74Schristos }
14775fd0b74Schristos
14875fd0b74Schristos
14975fd0b74Schristos /* Convert an arbitary arch_set - not necessarily corresponding
15075fd0b74Schristos directly to anything in the table above - to the most generic
15175fd0b74Schristos architecture which supports all the required features, and
15275fd0b74Schristos return the corresponding BFD mach. */
15375fd0b74Schristos
15475fd0b74Schristos unsigned long
sh_get_bfd_mach_from_arch_set(unsigned int arch_set)15575fd0b74Schristos sh_get_bfd_mach_from_arch_set (unsigned int arch_set)
15675fd0b74Schristos {
15775fd0b74Schristos unsigned long result = 0;
15875fd0b74Schristos unsigned int best = ~arch_set;
15975fd0b74Schristos unsigned int co_mask = ~0;
16075fd0b74Schristos int i = 0;
16175fd0b74Schristos
16275fd0b74Schristos /* If arch_set permits variants with no coprocessor then do not allow
16375fd0b74Schristos the other irrelevant co-processor bits to influence the choice:
16475fd0b74Schristos e.g. if dsp is disallowed by arch_set, then the algorithm would
16575fd0b74Schristos prefer fpu variants over nofpu variants because they also disallow
16675fd0b74Schristos dsp - even though the nofpu would be the most correct choice.
16775fd0b74Schristos This assumes that EVERY fpu/dsp variant has a no-coprocessor
16875fd0b74Schristos counter-part, or their non-fpu/dsp instructions do not have the
16975fd0b74Schristos no co-processor bit set. */
17075fd0b74Schristos if (arch_set & arch_sh_no_co)
17175fd0b74Schristos co_mask = ~(arch_sh_sp_fpu | arch_sh_dp_fpu | arch_sh_has_dsp);
17275fd0b74Schristos
17375fd0b74Schristos while (bfd_to_arch_table[i].bfd_mach != 0)
17475fd0b74Schristos {
17575fd0b74Schristos unsigned int try = bfd_to_arch_table[i].arch_up & co_mask;
17675fd0b74Schristos
17775fd0b74Schristos /* Conceptually: Find the architecture with the least number
17875fd0b74Schristos of extra features or, if they have the same number, then
17975fd0b74Schristos the greatest number of required features. Disregard
18075fd0b74Schristos architectures where the required features alone do
18175fd0b74Schristos not describe a valid architecture. */
18275fd0b74Schristos if (((try & ~arch_set) < (best & ~arch_set)
18375fd0b74Schristos || ((try & ~arch_set) == (best & ~arch_set)
18475fd0b74Schristos && (~try & arch_set) < (~best & arch_set)))
18575fd0b74Schristos && SH_MERGE_ARCH_SET_VALID (try, arch_set))
18675fd0b74Schristos {
18775fd0b74Schristos result = bfd_to_arch_table[i].bfd_mach;
18875fd0b74Schristos best = try;
18975fd0b74Schristos }
19075fd0b74Schristos
19175fd0b74Schristos i++;
19275fd0b74Schristos }
19375fd0b74Schristos
19475fd0b74Schristos /* This might happen if a new variant is added to sh-opc.h
19575fd0b74Schristos but no corresponding entry is added to the table above. */
19675fd0b74Schristos BFD_ASSERT (result != 0);
19775fd0b74Schristos
19875fd0b74Schristos return result;
19975fd0b74Schristos }
200