00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "bfd.h"
00027 #include "sysdep.h"
00028 #include "libbfd.h"
00029 #include "../opcodes/sh-opc.h"
00030
00031 #define SH_NEXT arch_info_struct + 0
00032 #define SH2_NEXT arch_info_struct + 1
00033 #define SH2E_NEXT arch_info_struct + 2
00034 #define SH_DSP_NEXT arch_info_struct + 3
00035 #define SH3_NEXT arch_info_struct + 4
00036 #define SH3_NOMMU_NEXT arch_info_struct + 5
00037 #define SH3_DSP_NEXT arch_info_struct + 6
00038 #define SH3E_NEXT arch_info_struct + 7
00039 #define SH4_NEXT arch_info_struct + 8
00040 #define SH4A_NEXT arch_info_struct + 9
00041 #define SH4AL_DSP_NEXT arch_info_struct + 10
00042 #define SH4_NOFPU_NEXT arch_info_struct + 11
00043 #define SH4_NOMMU_NOFPU_NEXT arch_info_struct + 12
00044 #define SH4A_NOFPU_NEXT arch_info_struct + 13
00045 #define SH2A_NEXT arch_info_struct + 14
00046 #define SH2A_NOFPU_NEXT arch_info_struct + 15
00047 #define SH2A_NOFPU_OR_SH4_NOMMU_NOFPU_NEXT arch_info_struct + 16
00048 #define SH2A_NOFPU_OR_SH3_NOMMU_NEXT arch_info_struct + 17
00049 #define SH2A_OR_SH4_NEXT arch_info_struct + 18
00050 #define SH2A_OR_SH3E_NEXT arch_info_struct + 19
00051 #define SH64_NEXT NULL
00052
00053 static const bfd_arch_info_type arch_info_struct[] =
00054 {
00055 {
00056 32,
00057 32,
00058 8,
00059 bfd_arch_sh,
00060 bfd_mach_sh2,
00061 "sh",
00062 "sh2",
00063 1,
00064 FALSE,
00065 bfd_default_compatible,
00066 bfd_default_scan,
00067 SH2_NEXT
00068 },
00069 {
00070 32,
00071 32,
00072 8,
00073 bfd_arch_sh,
00074 bfd_mach_sh2e,
00075 "sh",
00076 "sh2e",
00077 1,
00078 FALSE,
00079 bfd_default_compatible,
00080 bfd_default_scan,
00081 SH2E_NEXT
00082 },
00083 {
00084 32,
00085 32,
00086 8,
00087 bfd_arch_sh,
00088 bfd_mach_sh_dsp,
00089 "sh",
00090 "sh-dsp",
00091 1,
00092 FALSE,
00093 bfd_default_compatible,
00094 bfd_default_scan,
00095 SH_DSP_NEXT
00096 },
00097 {
00098 32,
00099 32,
00100 8,
00101 bfd_arch_sh,
00102 bfd_mach_sh3,
00103 "sh",
00104 "sh3",
00105 1,
00106 FALSE,
00107 bfd_default_compatible,
00108 bfd_default_scan,
00109 SH3_NEXT
00110 },
00111 {
00112 32,
00113 32,
00114 8,
00115 bfd_arch_sh,
00116 bfd_mach_sh3_nommu,
00117 "sh",
00118 "sh3-nommu",
00119 1,
00120 FALSE,
00121 bfd_default_compatible,
00122 bfd_default_scan,
00123 SH3_NOMMU_NEXT
00124 },
00125 {
00126 32,
00127 32,
00128 8,
00129 bfd_arch_sh,
00130 bfd_mach_sh3_dsp,
00131 "sh",
00132 "sh3-dsp",
00133 1,
00134 FALSE,
00135 bfd_default_compatible,
00136 bfd_default_scan,
00137 SH3_DSP_NEXT
00138 },
00139 {
00140 32,
00141 32,
00142 8,
00143 bfd_arch_sh,
00144 bfd_mach_sh3e,
00145 "sh",
00146 "sh3e",
00147 1,
00148 FALSE,
00149 bfd_default_compatible,
00150 bfd_default_scan,
00151 SH3E_NEXT
00152 },
00153 {
00154 32,
00155 32,
00156 8,
00157 bfd_arch_sh,
00158 bfd_mach_sh4,
00159 "sh",
00160 "sh4",
00161 1,
00162 FALSE,
00163 bfd_default_compatible,
00164 bfd_default_scan,
00165 SH4_NEXT
00166 },
00167 {
00168 32,
00169 32,
00170 8,
00171 bfd_arch_sh,
00172 bfd_mach_sh4a,
00173 "sh",
00174 "sh4a",
00175 1,
00176 FALSE,
00177 bfd_default_compatible,
00178 bfd_default_scan,
00179 SH4A_NEXT
00180 },
00181 {
00182 32,
00183 32,
00184 8,
00185 bfd_arch_sh,
00186 bfd_mach_sh4al_dsp,
00187 "sh",
00188 "sh4al-dsp",
00189 1,
00190 FALSE,
00191 bfd_default_compatible,
00192 bfd_default_scan,
00193 SH4AL_DSP_NEXT
00194 },
00195 {
00196 32,
00197 32,
00198 8,
00199 bfd_arch_sh,
00200 bfd_mach_sh4_nofpu,
00201 "sh",
00202 "sh4-nofpu",
00203 1,
00204 FALSE,
00205 bfd_default_compatible,
00206 bfd_default_scan,
00207 SH4_NOFPU_NEXT
00208 },
00209 {
00210 32,
00211 32,
00212 8,
00213 bfd_arch_sh,
00214 bfd_mach_sh4_nommu_nofpu,
00215 "sh",
00216 "sh4-nommu-nofpu",
00217 1,
00218 FALSE,
00219 bfd_default_compatible,
00220 bfd_default_scan,
00221 SH4_NOMMU_NOFPU_NEXT
00222 },
00223 {
00224 32,
00225 32,
00226 8,
00227 bfd_arch_sh,
00228 bfd_mach_sh4a_nofpu,
00229 "sh",
00230 "sh4a-nofpu",
00231 1,
00232 FALSE,
00233 bfd_default_compatible,
00234 bfd_default_scan,
00235 SH4A_NOFPU_NEXT
00236 },
00237 {
00238 32,
00239 32,
00240 8,
00241 bfd_arch_sh,
00242 bfd_mach_sh2a,
00243 "sh",
00244 "sh2a",
00245 1,
00246 FALSE,
00247 bfd_default_compatible,
00248 bfd_default_scan,
00249 SH2A_NEXT
00250 },
00251 {
00252 32,
00253 32,
00254 8,
00255 bfd_arch_sh,
00256 bfd_mach_sh2a_nofpu,
00257 "sh",
00258 "sh2a-nofpu",
00259 1,
00260 FALSE,
00261 bfd_default_compatible,
00262 bfd_default_scan,
00263 SH2A_NOFPU_NEXT
00264 },
00265 {
00266 32,
00267 32,
00268 8,
00269 bfd_arch_sh,
00270 bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu,
00271 "sh",
00272 "sh2a-nofpu-or-sh4-nommu-nofpu",
00273 1,
00274 FALSE,
00275 bfd_default_compatible,
00276 bfd_default_scan,
00277 SH2A_NOFPU_OR_SH4_NOMMU_NOFPU_NEXT
00278 },
00279 {
00280 32,
00281 32,
00282 8,
00283 bfd_arch_sh,
00284 bfd_mach_sh2a_nofpu_or_sh3_nommu,
00285 "sh",
00286 "sh2a-nofpu-or-sh3-nommu",
00287 1,
00288 FALSE,
00289 bfd_default_compatible,
00290 bfd_default_scan,
00291 SH2A_NOFPU_OR_SH3_NOMMU_NEXT
00292 },
00293 {
00294 32,
00295 32,
00296 8,
00297 bfd_arch_sh,
00298 bfd_mach_sh2a_or_sh4,
00299 "sh",
00300 "sh2a-or-sh4",
00301 1,
00302 FALSE,
00303 bfd_default_compatible,
00304 bfd_default_scan,
00305 SH2A_OR_SH4_NEXT
00306 },
00307 {
00308 32,
00309 32,
00310 8,
00311 bfd_arch_sh,
00312 bfd_mach_sh2a_or_sh3e,
00313 "sh",
00314 "sh2a-or-sh3e",
00315 1,
00316 FALSE,
00317 bfd_default_compatible,
00318 bfd_default_scan,
00319 SH2A_OR_SH3E_NEXT
00320 },
00321 {
00322 64,
00323 64,
00324 8,
00325 bfd_arch_sh,
00326 bfd_mach_sh5,
00327 "sh",
00328 "sh5",
00329 1,
00330 FALSE,
00331 bfd_default_compatible,
00332 bfd_default_scan,
00333 SH64_NEXT
00334 },
00335 };
00336
00337 const bfd_arch_info_type bfd_sh_arch =
00338 {
00339 32,
00340 32,
00341 8,
00342 bfd_arch_sh,
00343 bfd_mach_sh,
00344 "sh",
00345 "sh",
00346 1,
00347 TRUE,
00348 bfd_default_compatible,
00349 bfd_default_scan,
00350 SH_NEXT
00351 };
00352
00353
00354
00355
00356
00357
00358
00359
00360 static struct { unsigned long bfd_mach, arch, arch_up; } bfd_to_arch_table[] =
00361 {
00362 { bfd_mach_sh, arch_sh1, arch_sh_up },
00363 { bfd_mach_sh2, arch_sh2, arch_sh2_up },
00364 { bfd_mach_sh2e, arch_sh2e, arch_sh2e_up },
00365 { bfd_mach_sh_dsp, arch_sh_dsp, arch_sh_dsp_up },
00366 { bfd_mach_sh2a, arch_sh2a, arch_sh2a_up },
00367 { bfd_mach_sh2a_nofpu, arch_sh2a_nofpu, arch_sh2a_nofpu_up },
00368
00369 { bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu, arch_sh2a_nofpu_or_sh4_nommu_nofpu, arch_sh2a_nofpu_or_sh4_nommu_nofpu_up },
00370 { bfd_mach_sh2a_nofpu_or_sh3_nommu, arch_sh2a_nofpu_or_sh3_nommu, arch_sh2a_nofpu_or_sh3_nommu_up },
00371 { bfd_mach_sh2a_or_sh4, arch_sh2a_or_sh4, arch_sh2a_or_sh4_up },
00372 { bfd_mach_sh2a_or_sh3e, arch_sh2a_or_sh3e, arch_sh2a_or_sh3e_up },
00373
00374 { bfd_mach_sh3, arch_sh3, arch_sh3_up },
00375 { bfd_mach_sh3_nommu, arch_sh3_nommu, arch_sh3_nommu_up },
00376 { bfd_mach_sh3_dsp, arch_sh3_dsp, arch_sh3_dsp_up },
00377 { bfd_mach_sh3e, arch_sh3e, arch_sh3e_up },
00378 { bfd_mach_sh4, arch_sh4, arch_sh4_up },
00379 { bfd_mach_sh4a, arch_sh4a, arch_sh4a_up },
00380 { bfd_mach_sh4al_dsp, arch_sh4al_dsp, arch_sh4al_dsp_up },
00381 { bfd_mach_sh4_nofpu, arch_sh4_nofpu, arch_sh4_nofpu_up },
00382 { bfd_mach_sh4_nommu_nofpu, arch_sh4_nommu_nofpu, arch_sh4_nommu_nofpu_up },
00383 { bfd_mach_sh4a_nofpu, arch_sh4a_nofpu, arch_sh4a_nofpu_up },
00384 { 0, 0, 0 }
00385 };
00386
00387
00388
00389
00390
00391 unsigned int
00392 sh_get_arch_from_bfd_mach (unsigned long mach)
00393 {
00394 int i = 0;
00395
00396 while (bfd_to_arch_table[i].bfd_mach != 0)
00397 if (bfd_to_arch_table[i].bfd_mach == mach)
00398 return bfd_to_arch_table[i].arch;
00399 else
00400 i++;
00401
00402
00403 BFD_FAIL();
00404
00405 return SH_ARCH_UNKNOWN_ARCH;
00406 }
00407
00408
00409
00410
00411
00412
00413 unsigned int
00414 sh_get_arch_up_from_bfd_mach (unsigned long mach)
00415 {
00416 int i = 0;
00417
00418 while (bfd_to_arch_table[i].bfd_mach != 0)
00419 if (bfd_to_arch_table[i].bfd_mach == mach)
00420 return bfd_to_arch_table[i].arch_up;
00421 else
00422 i++;
00423
00424
00425 BFD_FAIL();
00426
00427 return SH_ARCH_UNKNOWN_ARCH;
00428 }
00429
00430
00431
00432
00433
00434
00435
00436 unsigned long
00437 sh_get_bfd_mach_from_arch_set (unsigned int arch_set)
00438 {
00439 unsigned long result = 0;
00440 unsigned int best = ~arch_set;
00441 unsigned int co_mask = ~0;
00442 int i = 0;
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452 if (arch_set & arch_sh_no_co)
00453 co_mask = ~(arch_sh_sp_fpu | arch_sh_dp_fpu | arch_sh_has_dsp);
00454
00455 while (bfd_to_arch_table[i].bfd_mach != 0)
00456 {
00457 unsigned int try = bfd_to_arch_table[i].arch_up & co_mask;
00458
00459
00460
00461
00462
00463
00464 if (((try & ~arch_set) < (best & ~arch_set)
00465 || ((try & ~arch_set) == (best & ~arch_set)
00466 && (~try & arch_set) < (~best & arch_set)))
00467 && SH_MERGE_ARCH_SET_VALID (try, arch_set))
00468 {
00469 result = bfd_to_arch_table[i].bfd_mach;
00470 best = try;
00471 }
00472
00473 i++;
00474 }
00475
00476
00477
00478 BFD_ASSERT (result != 0);
00479
00480 return result;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 bfd_boolean
00492 sh_merge_bfd_arch (bfd *ibfd, bfd *obfd)
00493 {
00494 unsigned int old_arch, new_arch, merged_arch;
00495
00496 if (! _bfd_generic_verify_endian_match (ibfd, obfd))
00497 return FALSE;
00498
00499 old_arch = sh_get_arch_up_from_bfd_mach (bfd_get_mach (obfd));
00500 new_arch = sh_get_arch_up_from_bfd_mach (bfd_get_mach (ibfd));
00501
00502 merged_arch = SH_MERGE_ARCH_SET (old_arch, new_arch);
00503
00504 if (!SH_VALID_CO_ARCH_SET (merged_arch))
00505 {
00506 (*_bfd_error_handler)
00507 ("%B: uses %s instructions while previous modules use %s instructions",
00508 ibfd,
00509 SH_ARCH_SET_HAS_DSP (new_arch) ? "dsp" : "floating point",
00510 SH_ARCH_SET_HAS_DSP (new_arch) ? "floating point" : "dsp");
00511 bfd_set_error (bfd_error_bad_value);
00512 return FALSE;
00513 }
00514 else if (!SH_VALID_ARCH_SET (merged_arch))
00515 {
00516 (*_bfd_error_handler)
00517 ("internal error: merge of architecture '%s' with architecture '%s' produced unknown architecture\n",
00518 bfd_printable_name (obfd),
00519 bfd_printable_name (ibfd));
00520 bfd_set_error (bfd_error_bad_value);
00521 return FALSE;
00522 }
00523
00524 bfd_default_set_arch_mach (obfd, bfd_arch_sh,
00525 sh_get_bfd_mach_from_arch_set (merged_arch));
00526
00527 return TRUE;
00528 }