xref: /openbsd-src/gnu/usr.bin/binutils-2.17/bfd/cpu-sh.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
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