Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/bfd/cpu-m68k.c
Line
Count
Source (jump to first uncovered line)
1
/* BFD library support routines for architectures.
2
   Copyright (C) 1990-2025 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
1.09M
{
154
1.09M
  unsigned ix;
155
156
3.59M
  for (ix = 0; mask; ix++)
157
    /* Clear the LSB set */
158
2.50M
    mask ^= mask & -mask;
159
1.09M
  return ix;
160
1.09M
}
161
162
/* Return the architectural features supported by MACH */
163
164
unsigned
165
bfd_m68k_mach_to_features (int mach)
166
3.82M
{
167
3.82M
  if ((unsigned)mach
168
3.82M
      >= sizeof (m68k_arch_features) / sizeof (m68k_arch_features[0]))
169
0
    mach = 0;
170
3.82M
  return m68k_arch_features[mach];
171
3.82M
}
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
19.6k
{
180
19.6k
  int superset = 0, subset = 0;
181
19.6k
  unsigned extra = 99, missing = 99;
182
19.6k
  unsigned ix;
183
184
19.6k
  for (ix = 0;
185
567k
       ix != sizeof (m68k_arch_features) / sizeof (m68k_arch_features[0]);
186
548k
       ix++)
187
553k
    {
188
553k
      unsigned this_extra, this_missing;
189
190
553k
      if (m68k_arch_features[ix] == features)
191
5.08k
  return ix;
192
548k
      this_extra = bit_count (m68k_arch_features[ix] & ~features);
193
548k
      if (this_extra < extra)
194
18.6k
  {
195
18.6k
    extra = this_extra;
196
18.6k
    superset = ix;
197
18.6k
  }
198
199
548k
      this_missing = bit_count (features & ~m68k_arch_features[ix]);
200
548k
      if (this_missing < missing)
201
58.6k
  {
202
58.6k
    missing = this_missing;
203
58.6k
    superset = ix;
204
58.6k
  }
205
548k
    }
206
14.5k
  return superset ? superset : subset;
207
19.6k
}
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
0
{
213
0
  if (a->arch != b->arch)
214
0
    return NULL;
215
216
0
  if (a->bits_per_word != b->bits_per_word)
217
0
    return NULL;
218
219
0
  if (!a->mach)
220
0
    return b;
221
0
  if (!b->mach)
222
0
    return a;
223
224
0
  if (a->mach <= bfd_mach_m68060 && b->mach <= bfd_mach_m68060)
225
    /* Merge m68k machine. */
226
0
    return a->mach > b->mach ? a : b;
227
0
  else if (a->mach >= bfd_mach_cpu32 && b->mach >= bfd_mach_cpu32)
228
0
    {
229
      /* Merge the machine features.  */
230
0
      unsigned features = (bfd_m68k_mach_to_features (a->mach)
231
0
         | bfd_m68k_mach_to_features (b->mach));
232
233
      /* CPU32 and Coldfire are incompatible.  */
234
0
      if ((~features & (cpu32 | mcfisa_a)) == 0)
235
0
  return NULL;
236
237
      /* Fido and Coldfire are incompatible.  */
238
0
      if ((~features & (fido_a | mcfisa_a)) == 0)
239
0
  return NULL;
240
241
      /* ISA A+ and ISA B are incompatible.  */
242
0
      if ((~features & (mcfisa_aa | mcfisa_b)) == 0)
243
0
  return NULL;
244
245
      /* ISA B and ISA C are incompatible.  */
246
0
      if ((~features & (mcfisa_b | mcfisa_c)) == 0)
247
0
  return NULL;
248
249
      /* MAC and EMAC code cannot be merged.  */
250
0
      if ((~features & (mcfmac | mcfemac)) == 0)
251
0
  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
0
      if ((a->mach == bfd_mach_cpu32 && b->mach == bfd_mach_fido)
257
0
    || (a->mach == bfd_mach_fido && b->mach == bfd_mach_cpu32))
258
0
  {
259
0
    static int cpu32_fido_mix_warning;
260
0
    if (!cpu32_fido_mix_warning)
261
0
      {
262
0
        cpu32_fido_mix_warning = 1;
263
0
        _bfd_error_handler ("warning: linking CPU32 objects with fido objects");
264
0
      }
265
0
    return bfd_lookup_arch (a->arch,
266
0
          bfd_m68k_features_to_mach (fido_a | m68881));
267
0
  }
268
269
0
      return bfd_lookup_arch (a->arch, bfd_m68k_features_to_mach (features));
270
0
    }
271
0
  else
272
    /* They are incompatible.  */
273
0
    return NULL;
274
0
}