1*3d8817e4Smiod /* BFD library support routines for the Renesas / SuperH SH architecture.
2*3d8817e4Smiod Copyright 1993, 1994, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005
3*3d8817e4Smiod Free Software Foundation, Inc.
4*3d8817e4Smiod Hacked by Steve Chamberlain of Cygnus Support.
5*3d8817e4Smiod
6*3d8817e4Smiod This file is part of BFD, the Binary File Descriptor library.
7*3d8817e4Smiod
8*3d8817e4Smiod This program is free software; you can redistribute it and/or modify
9*3d8817e4Smiod it under the terms of the GNU General Public License as published by
10*3d8817e4Smiod the Free Software Foundation; either version 2 of the License, or
11*3d8817e4Smiod (at your option) any later version.
12*3d8817e4Smiod
13*3d8817e4Smiod This program is distributed in the hope that it will be useful,
14*3d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of
15*3d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16*3d8817e4Smiod GNU General Public License for more details.
17*3d8817e4Smiod
18*3d8817e4Smiod You should have received a copy of the GNU General Public License
19*3d8817e4Smiod along with this program; if not, write to the Free Software
20*3d8817e4Smiod Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
21*3d8817e4Smiod
22*3d8817e4Smiod #include "bfd.h"
23*3d8817e4Smiod #include "sysdep.h"
24*3d8817e4Smiod #include "libbfd.h"
25*3d8817e4Smiod #include "../opcodes/sh-opc.h"
26*3d8817e4Smiod
27*3d8817e4Smiod #define SH_NEXT arch_info_struct + 0
28*3d8817e4Smiod #define SH2_NEXT arch_info_struct + 1
29*3d8817e4Smiod #define SH2E_NEXT arch_info_struct + 2
30*3d8817e4Smiod #define SH_DSP_NEXT arch_info_struct + 3
31*3d8817e4Smiod #define SH3_NEXT arch_info_struct + 4
32*3d8817e4Smiod #define SH3_NOMMU_NEXT arch_info_struct + 5
33*3d8817e4Smiod #define SH3_DSP_NEXT arch_info_struct + 6
34*3d8817e4Smiod #define SH3E_NEXT arch_info_struct + 7
35*3d8817e4Smiod #define SH4_NEXT arch_info_struct + 8
36*3d8817e4Smiod #define SH4A_NEXT arch_info_struct + 9
37*3d8817e4Smiod #define SH4AL_DSP_NEXT arch_info_struct + 10
38*3d8817e4Smiod #define SH4_NOFPU_NEXT arch_info_struct + 11
39*3d8817e4Smiod #define SH4_NOMMU_NOFPU_NEXT arch_info_struct + 12
40*3d8817e4Smiod #define SH4A_NOFPU_NEXT arch_info_struct + 13
41*3d8817e4Smiod #define SH2A_NEXT arch_info_struct + 14
42*3d8817e4Smiod #define SH2A_NOFPU_NEXT arch_info_struct + 15
43*3d8817e4Smiod #define SH2A_NOFPU_OR_SH4_NOMMU_NOFPU_NEXT arch_info_struct + 16
44*3d8817e4Smiod #define SH2A_NOFPU_OR_SH3_NOMMU_NEXT arch_info_struct + 17
45*3d8817e4Smiod #define SH2A_OR_SH4_NEXT arch_info_struct + 18
46*3d8817e4Smiod #define SH2A_OR_SH3E_NEXT arch_info_struct + 19
47*3d8817e4Smiod #define SH64_NEXT NULL
48*3d8817e4Smiod
49*3d8817e4Smiod static const bfd_arch_info_type arch_info_struct[] =
50*3d8817e4Smiod {
51*3d8817e4Smiod {
52*3d8817e4Smiod 32, /* 32 bits in a word. */
53*3d8817e4Smiod 32, /* 32 bits in an address. */
54*3d8817e4Smiod 8, /* 8 bits in a byte. */
55*3d8817e4Smiod bfd_arch_sh,
56*3d8817e4Smiod bfd_mach_sh2,
57*3d8817e4Smiod "sh", /* Architecture name. */
58*3d8817e4Smiod "sh2", /* Machine name. */
59*3d8817e4Smiod 1,
60*3d8817e4Smiod FALSE, /* Not the default. */
61*3d8817e4Smiod bfd_default_compatible,
62*3d8817e4Smiod bfd_default_scan,
63*3d8817e4Smiod SH2_NEXT
64*3d8817e4Smiod },
65*3d8817e4Smiod {
66*3d8817e4Smiod 32, /* 32 bits in a word. */
67*3d8817e4Smiod 32, /* 32 bits in an address. */
68*3d8817e4Smiod 8, /* 8 bits in a byte. */
69*3d8817e4Smiod bfd_arch_sh,
70*3d8817e4Smiod bfd_mach_sh2e,
71*3d8817e4Smiod "sh", /* Architecture name. */
72*3d8817e4Smiod "sh2e", /* Machine name. */
73*3d8817e4Smiod 1,
74*3d8817e4Smiod FALSE, /* Not the default. */
75*3d8817e4Smiod bfd_default_compatible,
76*3d8817e4Smiod bfd_default_scan,
77*3d8817e4Smiod SH2E_NEXT
78*3d8817e4Smiod },
79*3d8817e4Smiod {
80*3d8817e4Smiod 32, /* 32 bits in a word. */
81*3d8817e4Smiod 32, /* 32 bits in an address. */
82*3d8817e4Smiod 8, /* 8 bits in a byte. */
83*3d8817e4Smiod bfd_arch_sh,
84*3d8817e4Smiod bfd_mach_sh_dsp,
85*3d8817e4Smiod "sh", /* Architecture name. */
86*3d8817e4Smiod "sh-dsp", /* Machine name. */
87*3d8817e4Smiod 1,
88*3d8817e4Smiod FALSE, /* Not the default. */
89*3d8817e4Smiod bfd_default_compatible,
90*3d8817e4Smiod bfd_default_scan,
91*3d8817e4Smiod SH_DSP_NEXT
92*3d8817e4Smiod },
93*3d8817e4Smiod {
94*3d8817e4Smiod 32, /* 32 bits in a word. */
95*3d8817e4Smiod 32, /* 32 bits in an address. */
96*3d8817e4Smiod 8, /* 8 bits in a byte. */
97*3d8817e4Smiod bfd_arch_sh,
98*3d8817e4Smiod bfd_mach_sh3,
99*3d8817e4Smiod "sh", /* Architecture name. */
100*3d8817e4Smiod "sh3", /* Machine name. */
101*3d8817e4Smiod 1,
102*3d8817e4Smiod FALSE, /* Not the default. */
103*3d8817e4Smiod bfd_default_compatible,
104*3d8817e4Smiod bfd_default_scan,
105*3d8817e4Smiod SH3_NEXT
106*3d8817e4Smiod },
107*3d8817e4Smiod {
108*3d8817e4Smiod 32, /* 32 bits in a word. */
109*3d8817e4Smiod 32, /* 32 bits in an address. */
110*3d8817e4Smiod 8, /* 8 bits in a byte. */
111*3d8817e4Smiod bfd_arch_sh,
112*3d8817e4Smiod bfd_mach_sh3_nommu,
113*3d8817e4Smiod "sh", /* Architecture name. */
114*3d8817e4Smiod "sh3-nommu", /* Machine name. */
115*3d8817e4Smiod 1,
116*3d8817e4Smiod FALSE, /* Not the default. */
117*3d8817e4Smiod bfd_default_compatible,
118*3d8817e4Smiod bfd_default_scan,
119*3d8817e4Smiod SH3_NOMMU_NEXT
120*3d8817e4Smiod },
121*3d8817e4Smiod {
122*3d8817e4Smiod 32, /* 32 bits in a word. */
123*3d8817e4Smiod 32, /* 32 bits in an address. */
124*3d8817e4Smiod 8, /* 8 bits in a byte. */
125*3d8817e4Smiod bfd_arch_sh,
126*3d8817e4Smiod bfd_mach_sh3_dsp,
127*3d8817e4Smiod "sh", /* Architecture name. */
128*3d8817e4Smiod "sh3-dsp", /* Machine name. */
129*3d8817e4Smiod 1,
130*3d8817e4Smiod FALSE, /* Not the default. */
131*3d8817e4Smiod bfd_default_compatible,
132*3d8817e4Smiod bfd_default_scan,
133*3d8817e4Smiod SH3_DSP_NEXT
134*3d8817e4Smiod },
135*3d8817e4Smiod {
136*3d8817e4Smiod 32, /* 32 bits in a word. */
137*3d8817e4Smiod 32, /* 32 bits in an address. */
138*3d8817e4Smiod 8, /* 8 bits in a byte. */
139*3d8817e4Smiod bfd_arch_sh,
140*3d8817e4Smiod bfd_mach_sh3e,
141*3d8817e4Smiod "sh", /* Architecture name. */
142*3d8817e4Smiod "sh3e", /* Machine name. */
143*3d8817e4Smiod 1,
144*3d8817e4Smiod FALSE, /* Not the default. */
145*3d8817e4Smiod bfd_default_compatible,
146*3d8817e4Smiod bfd_default_scan,
147*3d8817e4Smiod SH3E_NEXT
148*3d8817e4Smiod },
149*3d8817e4Smiod {
150*3d8817e4Smiod 32, /* 32 bits in a word. */
151*3d8817e4Smiod 32, /* 32 bits in an address. */
152*3d8817e4Smiod 8, /* 8 bits in a byte. */
153*3d8817e4Smiod bfd_arch_sh,
154*3d8817e4Smiod bfd_mach_sh4,
155*3d8817e4Smiod "sh", /* Architecture name. */
156*3d8817e4Smiod "sh4", /* Machine name. */
157*3d8817e4Smiod 1,
158*3d8817e4Smiod FALSE, /* Not the default. */
159*3d8817e4Smiod bfd_default_compatible,
160*3d8817e4Smiod bfd_default_scan,
161*3d8817e4Smiod SH4_NEXT
162*3d8817e4Smiod },
163*3d8817e4Smiod {
164*3d8817e4Smiod 32, /* 32 bits in a word. */
165*3d8817e4Smiod 32, /* 32 bits in an address. */
166*3d8817e4Smiod 8, /* 8 bits in a byte. */
167*3d8817e4Smiod bfd_arch_sh,
168*3d8817e4Smiod bfd_mach_sh4a,
169*3d8817e4Smiod "sh", /* Architecture name. */
170*3d8817e4Smiod "sh4a", /* Machine name. */
171*3d8817e4Smiod 1,
172*3d8817e4Smiod FALSE, /* Not the default. */
173*3d8817e4Smiod bfd_default_compatible,
174*3d8817e4Smiod bfd_default_scan,
175*3d8817e4Smiod SH4A_NEXT
176*3d8817e4Smiod },
177*3d8817e4Smiod {
178*3d8817e4Smiod 32, /* 32 bits in a word. */
179*3d8817e4Smiod 32, /* 32 bits in an address. */
180*3d8817e4Smiod 8, /* 8 bits in a byte. */
181*3d8817e4Smiod bfd_arch_sh,
182*3d8817e4Smiod bfd_mach_sh4al_dsp,
183*3d8817e4Smiod "sh", /* Architecture name. */
184*3d8817e4Smiod "sh4al-dsp", /* Machine name. */
185*3d8817e4Smiod 1,
186*3d8817e4Smiod FALSE, /* Not the default. */
187*3d8817e4Smiod bfd_default_compatible,
188*3d8817e4Smiod bfd_default_scan,
189*3d8817e4Smiod SH4AL_DSP_NEXT
190*3d8817e4Smiod },
191*3d8817e4Smiod {
192*3d8817e4Smiod 32, /* 32 bits in a word. */
193*3d8817e4Smiod 32, /* 32 bits in an address. */
194*3d8817e4Smiod 8, /* 8 bits in a byte. */
195*3d8817e4Smiod bfd_arch_sh,
196*3d8817e4Smiod bfd_mach_sh4_nofpu,
197*3d8817e4Smiod "sh", /* Architecture name. */
198*3d8817e4Smiod "sh4-nofpu", /* Machine name. */
199*3d8817e4Smiod 1,
200*3d8817e4Smiod FALSE, /* Not the default. */
201*3d8817e4Smiod bfd_default_compatible,
202*3d8817e4Smiod bfd_default_scan,
203*3d8817e4Smiod SH4_NOFPU_NEXT
204*3d8817e4Smiod },
205*3d8817e4Smiod {
206*3d8817e4Smiod 32, /* 32 bits in a word. */
207*3d8817e4Smiod 32, /* 32 bits in an address. */
208*3d8817e4Smiod 8, /* 8 bits in a byte. */
209*3d8817e4Smiod bfd_arch_sh,
210*3d8817e4Smiod bfd_mach_sh4_nommu_nofpu,
211*3d8817e4Smiod "sh", /* Architecture name. */
212*3d8817e4Smiod "sh4-nommu-nofpu", /* Machine name. */
213*3d8817e4Smiod 1,
214*3d8817e4Smiod FALSE, /* Not the default. */
215*3d8817e4Smiod bfd_default_compatible,
216*3d8817e4Smiod bfd_default_scan,
217*3d8817e4Smiod SH4_NOMMU_NOFPU_NEXT
218*3d8817e4Smiod },
219*3d8817e4Smiod {
220*3d8817e4Smiod 32, /* 32 bits in a word. */
221*3d8817e4Smiod 32, /* 32 bits in an address. */
222*3d8817e4Smiod 8, /* 8 bits in a byte. */
223*3d8817e4Smiod bfd_arch_sh,
224*3d8817e4Smiod bfd_mach_sh4a_nofpu,
225*3d8817e4Smiod "sh", /* Architecture name. */
226*3d8817e4Smiod "sh4a-nofpu", /* Machine name. */
227*3d8817e4Smiod 1,
228*3d8817e4Smiod FALSE, /* Not the default. */
229*3d8817e4Smiod bfd_default_compatible,
230*3d8817e4Smiod bfd_default_scan,
231*3d8817e4Smiod SH4A_NOFPU_NEXT
232*3d8817e4Smiod },
233*3d8817e4Smiod {
234*3d8817e4Smiod 32, /* 32 bits in a word. */
235*3d8817e4Smiod 32, /* 32 bits in an address. */
236*3d8817e4Smiod 8, /* 8 bits in a byte. */
237*3d8817e4Smiod bfd_arch_sh,
238*3d8817e4Smiod bfd_mach_sh2a,
239*3d8817e4Smiod "sh", /* Architecture name. */
240*3d8817e4Smiod "sh2a", /* Machine name. */
241*3d8817e4Smiod 1,
242*3d8817e4Smiod FALSE, /* Not the default. */
243*3d8817e4Smiod bfd_default_compatible,
244*3d8817e4Smiod bfd_default_scan,
245*3d8817e4Smiod SH2A_NEXT
246*3d8817e4Smiod },
247*3d8817e4Smiod {
248*3d8817e4Smiod 32, /* 32 bits in a word. */
249*3d8817e4Smiod 32, /* 32 bits in an address. */
250*3d8817e4Smiod 8, /* 8 bits in a byte. */
251*3d8817e4Smiod bfd_arch_sh,
252*3d8817e4Smiod bfd_mach_sh2a_nofpu,
253*3d8817e4Smiod "sh", /* Architecture name. */
254*3d8817e4Smiod "sh2a-nofpu", /* Machine name. */
255*3d8817e4Smiod 1,
256*3d8817e4Smiod FALSE, /* Not the default. */
257*3d8817e4Smiod bfd_default_compatible,
258*3d8817e4Smiod bfd_default_scan,
259*3d8817e4Smiod SH2A_NOFPU_NEXT
260*3d8817e4Smiod },
261*3d8817e4Smiod {
262*3d8817e4Smiod 32, /* 32 bits in a word. */
263*3d8817e4Smiod 32, /* 32 bits in an address. */
264*3d8817e4Smiod 8, /* 8 bits in a byte. */
265*3d8817e4Smiod bfd_arch_sh,
266*3d8817e4Smiod bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu,
267*3d8817e4Smiod "sh", /* Architecture name. */
268*3d8817e4Smiod "sh2a-nofpu-or-sh4-nommu-nofpu", /* Machine name. */
269*3d8817e4Smiod 1,
270*3d8817e4Smiod FALSE, /* Not the default. */
271*3d8817e4Smiod bfd_default_compatible,
272*3d8817e4Smiod bfd_default_scan,
273*3d8817e4Smiod SH2A_NOFPU_OR_SH4_NOMMU_NOFPU_NEXT
274*3d8817e4Smiod },
275*3d8817e4Smiod {
276*3d8817e4Smiod 32, /* 32 bits in a word. */
277*3d8817e4Smiod 32, /* 32 bits in an address. */
278*3d8817e4Smiod 8, /* 8 bits in a byte. */
279*3d8817e4Smiod bfd_arch_sh,
280*3d8817e4Smiod bfd_mach_sh2a_nofpu_or_sh3_nommu,
281*3d8817e4Smiod "sh", /* Architecture name. . */
282*3d8817e4Smiod "sh2a-nofpu-or-sh3-nommu", /* Machine name. */
283*3d8817e4Smiod 1,
284*3d8817e4Smiod FALSE, /* Not the default. */
285*3d8817e4Smiod bfd_default_compatible,
286*3d8817e4Smiod bfd_default_scan,
287*3d8817e4Smiod SH2A_NOFPU_OR_SH3_NOMMU_NEXT
288*3d8817e4Smiod },
289*3d8817e4Smiod {
290*3d8817e4Smiod 32, /* 32 bits in a word. */
291*3d8817e4Smiod 32, /* 32 bits in an address. */
292*3d8817e4Smiod 8, /* 8 bits in a byte. */
293*3d8817e4Smiod bfd_arch_sh,
294*3d8817e4Smiod bfd_mach_sh2a_or_sh4,
295*3d8817e4Smiod "sh", /* Architecture name. */
296*3d8817e4Smiod "sh2a-or-sh4", /* Machine name. */
297*3d8817e4Smiod 1,
298*3d8817e4Smiod FALSE, /* Not the default. */
299*3d8817e4Smiod bfd_default_compatible,
300*3d8817e4Smiod bfd_default_scan,
301*3d8817e4Smiod SH2A_OR_SH4_NEXT
302*3d8817e4Smiod },
303*3d8817e4Smiod {
304*3d8817e4Smiod 32, /* 32 bits in a word. */
305*3d8817e4Smiod 32, /* 32 bits in an address. */
306*3d8817e4Smiod 8, /* 8 bits in a byte. */
307*3d8817e4Smiod bfd_arch_sh,
308*3d8817e4Smiod bfd_mach_sh2a_or_sh3e,
309*3d8817e4Smiod "sh", /* Architecture name. */
310*3d8817e4Smiod "sh2a-or-sh3e", /* Machine name. */
311*3d8817e4Smiod 1,
312*3d8817e4Smiod FALSE, /* Not the default. */
313*3d8817e4Smiod bfd_default_compatible,
314*3d8817e4Smiod bfd_default_scan,
315*3d8817e4Smiod SH2A_OR_SH3E_NEXT
316*3d8817e4Smiod },
317*3d8817e4Smiod {
318*3d8817e4Smiod 64, /* 64 bits in a word. */
319*3d8817e4Smiod 64, /* 64 bits in an address. */
320*3d8817e4Smiod 8, /* 8 bits in a byte. */
321*3d8817e4Smiod bfd_arch_sh,
322*3d8817e4Smiod bfd_mach_sh5,
323*3d8817e4Smiod "sh", /* Architecture name. */
324*3d8817e4Smiod "sh5", /* Machine name. */
325*3d8817e4Smiod 1,
326*3d8817e4Smiod FALSE, /* Not the default. */
327*3d8817e4Smiod bfd_default_compatible,
328*3d8817e4Smiod bfd_default_scan,
329*3d8817e4Smiod SH64_NEXT
330*3d8817e4Smiod },
331*3d8817e4Smiod };
332*3d8817e4Smiod
333*3d8817e4Smiod const bfd_arch_info_type bfd_sh_arch =
334*3d8817e4Smiod {
335*3d8817e4Smiod 32, /* 32 bits in a word. */
336*3d8817e4Smiod 32, /* 32 bits in an address. */
337*3d8817e4Smiod 8, /* 8 bits in a byte. */
338*3d8817e4Smiod bfd_arch_sh,
339*3d8817e4Smiod bfd_mach_sh,
340*3d8817e4Smiod "sh", /* Architecture name. */
341*3d8817e4Smiod "sh", /* Machine name. */
342*3d8817e4Smiod 1,
343*3d8817e4Smiod TRUE, /* The default machine. */
344*3d8817e4Smiod bfd_default_compatible,
345*3d8817e4Smiod bfd_default_scan,
346*3d8817e4Smiod SH_NEXT
347*3d8817e4Smiod };
348*3d8817e4Smiod
349*3d8817e4Smiod
350*3d8817e4Smiod /* This table defines the mappings from the BFD internal numbering
351*3d8817e4Smiod system to the opcodes internal flags system.
352*3d8817e4Smiod It is used by the functions defined below.
353*3d8817e4Smiod The prototypes for these SH specific functions are found in
354*3d8817e4Smiod sh-opc.h . */
355*3d8817e4Smiod
356*3d8817e4Smiod static struct { unsigned long bfd_mach, arch, arch_up; } bfd_to_arch_table[] =
357*3d8817e4Smiod {
358*3d8817e4Smiod { bfd_mach_sh, arch_sh1, arch_sh_up },
359*3d8817e4Smiod { bfd_mach_sh2, arch_sh2, arch_sh2_up },
360*3d8817e4Smiod { bfd_mach_sh2e, arch_sh2e, arch_sh2e_up },
361*3d8817e4Smiod { bfd_mach_sh_dsp, arch_sh_dsp, arch_sh_dsp_up },
362*3d8817e4Smiod { bfd_mach_sh2a, arch_sh2a, arch_sh2a_up },
363*3d8817e4Smiod { bfd_mach_sh2a_nofpu, arch_sh2a_nofpu, arch_sh2a_nofpu_up },
364*3d8817e4Smiod
365*3d8817e4Smiod { bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu, arch_sh2a_nofpu_or_sh4_nommu_nofpu, arch_sh2a_nofpu_or_sh4_nommu_nofpu_up },
366*3d8817e4Smiod { bfd_mach_sh2a_nofpu_or_sh3_nommu, arch_sh2a_nofpu_or_sh3_nommu, arch_sh2a_nofpu_or_sh3_nommu_up },
367*3d8817e4Smiod { bfd_mach_sh2a_or_sh4, arch_sh2a_or_sh4, arch_sh2a_or_sh4_up },
368*3d8817e4Smiod { bfd_mach_sh2a_or_sh3e, arch_sh2a_or_sh3e, arch_sh2a_or_sh3e_up },
369*3d8817e4Smiod
370*3d8817e4Smiod { bfd_mach_sh3, arch_sh3, arch_sh3_up },
371*3d8817e4Smiod { bfd_mach_sh3_nommu, arch_sh3_nommu, arch_sh3_nommu_up },
372*3d8817e4Smiod { bfd_mach_sh3_dsp, arch_sh3_dsp, arch_sh3_dsp_up },
373*3d8817e4Smiod { bfd_mach_sh3e, arch_sh3e, arch_sh3e_up },
374*3d8817e4Smiod { bfd_mach_sh4, arch_sh4, arch_sh4_up },
375*3d8817e4Smiod { bfd_mach_sh4a, arch_sh4a, arch_sh4a_up },
376*3d8817e4Smiod { bfd_mach_sh4al_dsp, arch_sh4al_dsp, arch_sh4al_dsp_up },
377*3d8817e4Smiod { bfd_mach_sh4_nofpu, arch_sh4_nofpu, arch_sh4_nofpu_up },
378*3d8817e4Smiod { bfd_mach_sh4_nommu_nofpu, arch_sh4_nommu_nofpu, arch_sh4_nommu_nofpu_up },
379*3d8817e4Smiod { bfd_mach_sh4a_nofpu, arch_sh4a_nofpu, arch_sh4a_nofpu_up },
380*3d8817e4Smiod { 0, 0, 0 } /* Terminator. */
381*3d8817e4Smiod };
382*3d8817e4Smiod
383*3d8817e4Smiod
384*3d8817e4Smiod /* Convert a BFD mach number into the right opcodes arch flags
385*3d8817e4Smiod using the table above. */
386*3d8817e4Smiod
387*3d8817e4Smiod unsigned int
sh_get_arch_from_bfd_mach(unsigned long mach)388*3d8817e4Smiod sh_get_arch_from_bfd_mach (unsigned long mach)
389*3d8817e4Smiod {
390*3d8817e4Smiod int i = 0;
391*3d8817e4Smiod
392*3d8817e4Smiod while (bfd_to_arch_table[i].bfd_mach != 0)
393*3d8817e4Smiod if (bfd_to_arch_table[i].bfd_mach == mach)
394*3d8817e4Smiod return bfd_to_arch_table[i].arch;
395*3d8817e4Smiod else
396*3d8817e4Smiod i++;
397*3d8817e4Smiod
398*3d8817e4Smiod /* Machine not found. */
399*3d8817e4Smiod BFD_FAIL();
400*3d8817e4Smiod
401*3d8817e4Smiod return SH_ARCH_UNKNOWN_ARCH;
402*3d8817e4Smiod }
403*3d8817e4Smiod
404*3d8817e4Smiod
405*3d8817e4Smiod /* Convert a BFD mach number into a set of opcodes arch flags
406*3d8817e4Smiod describing all the compatible architectures (i.e. arch_up)
407*3d8817e4Smiod using the table above. */
408*3d8817e4Smiod
409*3d8817e4Smiod unsigned int
sh_get_arch_up_from_bfd_mach(unsigned long mach)410*3d8817e4Smiod sh_get_arch_up_from_bfd_mach (unsigned long mach)
411*3d8817e4Smiod {
412*3d8817e4Smiod int i = 0;
413*3d8817e4Smiod
414*3d8817e4Smiod while (bfd_to_arch_table[i].bfd_mach != 0)
415*3d8817e4Smiod if (bfd_to_arch_table[i].bfd_mach == mach)
416*3d8817e4Smiod return bfd_to_arch_table[i].arch_up;
417*3d8817e4Smiod else
418*3d8817e4Smiod i++;
419*3d8817e4Smiod
420*3d8817e4Smiod /* Machine not found. */
421*3d8817e4Smiod BFD_FAIL();
422*3d8817e4Smiod
423*3d8817e4Smiod return SH_ARCH_UNKNOWN_ARCH;
424*3d8817e4Smiod }
425*3d8817e4Smiod
426*3d8817e4Smiod
427*3d8817e4Smiod /* Convert an arbitary arch_set - not necessarily corresponding
428*3d8817e4Smiod directly to anything in the table above - to the most generic
429*3d8817e4Smiod architecture which supports all the required features, and
430*3d8817e4Smiod return the corresponding BFD mach. */
431*3d8817e4Smiod
432*3d8817e4Smiod unsigned long
sh_get_bfd_mach_from_arch_set(unsigned int arch_set)433*3d8817e4Smiod sh_get_bfd_mach_from_arch_set (unsigned int arch_set)
434*3d8817e4Smiod {
435*3d8817e4Smiod unsigned long result = 0;
436*3d8817e4Smiod unsigned int best = ~arch_set;
437*3d8817e4Smiod unsigned int co_mask = ~0;
438*3d8817e4Smiod int i = 0;
439*3d8817e4Smiod
440*3d8817e4Smiod /* If arch_set permits variants with no coprocessor then do not allow
441*3d8817e4Smiod the other irrelevant co-processor bits to influence the choice:
442*3d8817e4Smiod e.g. if dsp is disallowed by arch_set, then the algorithm would
443*3d8817e4Smiod prefer fpu variants over nofpu variants because they also disallow
444*3d8817e4Smiod dsp - even though the nofpu would be the most correct choice.
445*3d8817e4Smiod This assumes that EVERY fpu/dsp variant has a no-coprocessor
446*3d8817e4Smiod counter-part, or their non-fpu/dsp instructions do not have the
447*3d8817e4Smiod no co-processor bit set. */
448*3d8817e4Smiod if (arch_set & arch_sh_no_co)
449*3d8817e4Smiod co_mask = ~(arch_sh_sp_fpu | arch_sh_dp_fpu | arch_sh_has_dsp);
450*3d8817e4Smiod
451*3d8817e4Smiod while (bfd_to_arch_table[i].bfd_mach != 0)
452*3d8817e4Smiod {
453*3d8817e4Smiod unsigned int try = bfd_to_arch_table[i].arch_up & co_mask;
454*3d8817e4Smiod
455*3d8817e4Smiod /* Conceptually: Find the architecture with the least number
456*3d8817e4Smiod of extra features or, if they have the same number, then
457*3d8817e4Smiod the greatest number of required features. Disregard
458*3d8817e4Smiod architectures where the required features alone do
459*3d8817e4Smiod not describe a valid architecture. */
460*3d8817e4Smiod if (((try & ~arch_set) < (best & ~arch_set)
461*3d8817e4Smiod || ((try & ~arch_set) == (best & ~arch_set)
462*3d8817e4Smiod && (~try & arch_set) < (~best & arch_set)))
463*3d8817e4Smiod && SH_MERGE_ARCH_SET_VALID (try, arch_set))
464*3d8817e4Smiod {
465*3d8817e4Smiod result = bfd_to_arch_table[i].bfd_mach;
466*3d8817e4Smiod best = try;
467*3d8817e4Smiod }
468*3d8817e4Smiod
469*3d8817e4Smiod i++;
470*3d8817e4Smiod }
471*3d8817e4Smiod
472*3d8817e4Smiod /* This might happen if a new variant is added to sh-opc.h
473*3d8817e4Smiod but no corresponding entry is added to the table above. */
474*3d8817e4Smiod BFD_ASSERT (result != 0);
475*3d8817e4Smiod
476*3d8817e4Smiod return result;
477*3d8817e4Smiod }
478*3d8817e4Smiod
479*3d8817e4Smiod
480*3d8817e4Smiod /* Merge the architecture type of two BFD files, such that the
481*3d8817e4Smiod resultant architecture supports all the features required
482*3d8817e4Smiod by the two input BFDs.
483*3d8817e4Smiod If the input BFDs are multually incompatible - i.e. one uses
484*3d8817e4Smiod DSP while the other uses FPU - or there is no known architecture
485*3d8817e4Smiod that fits the requirements then an error is emitted. */
486*3d8817e4Smiod
487*3d8817e4Smiod bfd_boolean
sh_merge_bfd_arch(bfd * ibfd,bfd * obfd)488*3d8817e4Smiod sh_merge_bfd_arch (bfd *ibfd, bfd *obfd)
489*3d8817e4Smiod {
490*3d8817e4Smiod unsigned int old_arch, new_arch, merged_arch;
491*3d8817e4Smiod
492*3d8817e4Smiod if (! _bfd_generic_verify_endian_match (ibfd, obfd))
493*3d8817e4Smiod return FALSE;
494*3d8817e4Smiod
495*3d8817e4Smiod old_arch = sh_get_arch_up_from_bfd_mach (bfd_get_mach (obfd));
496*3d8817e4Smiod new_arch = sh_get_arch_up_from_bfd_mach (bfd_get_mach (ibfd));
497*3d8817e4Smiod
498*3d8817e4Smiod merged_arch = SH_MERGE_ARCH_SET (old_arch, new_arch);
499*3d8817e4Smiod
500*3d8817e4Smiod if (!SH_VALID_CO_ARCH_SET (merged_arch))
501*3d8817e4Smiod {
502*3d8817e4Smiod (*_bfd_error_handler)
503*3d8817e4Smiod ("%B: uses %s instructions while previous modules use %s instructions",
504*3d8817e4Smiod ibfd,
505*3d8817e4Smiod SH_ARCH_SET_HAS_DSP (new_arch) ? "dsp" : "floating point",
506*3d8817e4Smiod SH_ARCH_SET_HAS_DSP (new_arch) ? "floating point" : "dsp");
507*3d8817e4Smiod bfd_set_error (bfd_error_bad_value);
508*3d8817e4Smiod return FALSE;
509*3d8817e4Smiod }
510*3d8817e4Smiod else if (!SH_VALID_ARCH_SET (merged_arch))
511*3d8817e4Smiod {
512*3d8817e4Smiod (*_bfd_error_handler)
513*3d8817e4Smiod ("internal error: merge of architecture '%s' with architecture '%s' produced unknown architecture\n",
514*3d8817e4Smiod bfd_printable_name (obfd),
515*3d8817e4Smiod bfd_printable_name (ibfd));
516*3d8817e4Smiod bfd_set_error (bfd_error_bad_value);
517*3d8817e4Smiod return FALSE;
518*3d8817e4Smiod }
519*3d8817e4Smiod
520*3d8817e4Smiod bfd_default_set_arch_mach (obfd, bfd_arch_sh,
521*3d8817e4Smiod sh_get_bfd_mach_from_arch_set (merged_arch));
522*3d8817e4Smiod
523*3d8817e4Smiod return TRUE;
524*3d8817e4Smiod }
525