cpu-arm.c revision 77298
160484Sobrien/* BFD support for the ARM processor 260484Sobrien Copyright 1994, 95, 97, 1999 Free Software Foundation, Inc. 360484Sobrien Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) 460484Sobrien 560484SobrienThis file is part of BFD, the Binary File Descriptor library. 660484Sobrien 760484SobrienThis program is free software; you can redistribute it and/or modify 860484Sobrienit under the terms of the GNU General Public License as published by 960484Sobrienthe Free Software Foundation; either version 2 of the License, or 1060484Sobrien(at your option) any later version. 1160484Sobrien 1260484SobrienThis program is distributed in the hope that it will be useful, 1360484Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of 1460484SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1560484SobrienGNU General Public License for more details. 1660484Sobrien 1760484SobrienYou should have received a copy of the GNU General Public License 1860484Sobrienalong with this program; if not, write to the Free Software 1960484SobrienFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 2060484Sobrien 2160484Sobrien#include "bfd.h" 2260484Sobrien#include "sysdep.h" 2360484Sobrien#include "libbfd.h" 2460484Sobrien 2560484Sobrienstatic const bfd_arch_info_type *compatible 2660484Sobrien PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *)); 2760484Sobrienstatic boolean scan PARAMS ((const struct bfd_arch_info *, const char *)); 2860484Sobrien 2960484Sobrien/* This routine is provided two arch_infos and works out which ARM 3060484Sobrien machine which would be compatible with both and returns a pointer 3160484Sobrien to its info structure */ 3260484Sobrien 3360484Sobrienstatic const bfd_arch_info_type * 3460484Sobriencompatible (a,b) 3560484Sobrien const bfd_arch_info_type * a; 3660484Sobrien const bfd_arch_info_type * b; 3760484Sobrien{ 3860484Sobrien /* If a & b are for different architecture we can do nothing */ 3960484Sobrien if (a->arch != b->arch) 4060484Sobrien return NULL; 4160484Sobrien 4260484Sobrien /* If a & b are for the same machine then all is well */ 4360484Sobrien if (a->mach == b->mach) 4460484Sobrien return a; 4560484Sobrien 4660484Sobrien /* Otherwise if either a or b is the 'default' machine then 4760484Sobrien it can be polymorphed into the other */ 4860484Sobrien if (a->the_default) 4960484Sobrien return b; 5077298Sobrien 5160484Sobrien if (b->the_default) 5260484Sobrien return a; 5360484Sobrien 5460484Sobrien /* So far all newer ARM architecture cores are supersets of previous cores */ 5560484Sobrien if (a->mach < b->mach) 5660484Sobrien return b; 5760484Sobrien else if (a->mach > b->mach) 5860484Sobrien return a; 5960484Sobrien 6060484Sobrien /* Never reached! */ 6160484Sobrien return NULL; 6260484Sobrien} 6360484Sobrien 6460484Sobrienstatic struct 6560484Sobrien{ 6660484Sobrien enum bfd_architecture arch; 6760484Sobrien char * name; 6860484Sobrien} 6960484Sobrienprocessors[] = 7060484Sobrien{ 7160484Sobrien { bfd_mach_arm_2, "arm2" }, 7260484Sobrien { bfd_mach_arm_2a, "arm250" }, 7360484Sobrien { bfd_mach_arm_2a, "arm3" }, 7460484Sobrien { bfd_mach_arm_3, "arm6" }, 7560484Sobrien { bfd_mach_arm_3, "arm60" }, 7660484Sobrien { bfd_mach_arm_3, "arm600" }, 7760484Sobrien { bfd_mach_arm_3, "arm610" }, 7860484Sobrien { bfd_mach_arm_3, "arm7" }, 7960484Sobrien { bfd_mach_arm_3, "arm710" }, 8060484Sobrien { bfd_mach_arm_3, "arm7500" }, 8160484Sobrien { bfd_mach_arm_3, "arm7d" }, 8260484Sobrien { bfd_mach_arm_3, "arm7di" }, 8360484Sobrien { bfd_mach_arm_3M, "arm7dm" }, 8460484Sobrien { bfd_mach_arm_3M, "arm7dmi" }, 8560484Sobrien { bfd_mach_arm_4T, "arm7tdmi" }, 8660484Sobrien { bfd_mach_arm_4, "arm8" }, 8760484Sobrien { bfd_mach_arm_4, "arm810" }, 8860484Sobrien { bfd_mach_arm_4, "arm9" }, 8960484Sobrien { bfd_mach_arm_4, "arm920" }, 9060484Sobrien { bfd_mach_arm_4T, "arm920t" }, 9160484Sobrien { bfd_mach_arm_4T, "arm9tdmi" }, 9260484Sobrien { bfd_mach_arm_4, "sa1" }, 9360484Sobrien { bfd_mach_arm_4, "strongarm"}, 9460484Sobrien { bfd_mach_arm_4, "strongarm110" }, 9560484Sobrien { bfd_mach_arm_4, "strongarm1100" }, 9677298Sobrien { bfd_mach_arm_XScale, "xscale" } 9760484Sobrien}; 9860484Sobrien 9977298Sobrienstatic boolean 10060484Sobrienscan (info, string) 10160484Sobrien const struct bfd_arch_info * info; 10260484Sobrien const char * string; 10360484Sobrien{ 10460484Sobrien int i; 10560484Sobrien 10660484Sobrien /* First test for an exact match */ 10760484Sobrien if (strcasecmp (string, info->printable_name) == 0) 10860484Sobrien return true; 10960484Sobrien 11060484Sobrien /* Next check for a processor name instead of an Architecture name */ 11160484Sobrien for (i = sizeof (processors) / sizeof (processors[0]); i--;) 11260484Sobrien { 11360484Sobrien if (strcasecmp (string, processors[ i ].name) == 0) 11460484Sobrien break; 11560484Sobrien } 11660484Sobrien 11760484Sobrien if (i != -1 && info->arch == processors[ i ].arch) 11860484Sobrien return true; 11960484Sobrien 12060484Sobrien /* Finally check for the default architecture */ 12160484Sobrien if (strcasecmp (string, "arm") == 0) 12260484Sobrien return info->the_default; 12377298Sobrien 12460484Sobrien return false; 12560484Sobrien} 12660484Sobrien 12760484Sobrien#define N(number, print, default, next) \ 12860484Sobrien{ 32, 32, 8, bfd_arch_arm, number, "arm", print, 4, default, compatible, scan, next } 12960484Sobrien 13060484Sobrienstatic const bfd_arch_info_type arch_info_struct[] = 13177298Sobrien{ 13260484Sobrien N( bfd_mach_arm_2, "armv2", false, & arch_info_struct[1] ), 13360484Sobrien N( bfd_mach_arm_2a, "armv2a", false, & arch_info_struct[2] ), 13460484Sobrien N( bfd_mach_arm_3, "armv3", false, & arch_info_struct[3] ), 13560484Sobrien N( bfd_mach_arm_3M, "armv3m", false, & arch_info_struct[4] ), 13660484Sobrien N( bfd_mach_arm_4, "armv4", false, & arch_info_struct[5] ), 13760484Sobrien N( bfd_mach_arm_4T, "armv4t", false, & arch_info_struct[6] ), 13860484Sobrien N( bfd_mach_arm_5, "armv5", false, & arch_info_struct[7] ), 13977298Sobrien N( bfd_mach_arm_5T, "armv5t", false, & arch_info_struct[8] ), 14077298Sobrien N( bfd_mach_arm_5TE, "armv5te", false, & arch_info_struct[9] ), 14177298Sobrien N( bfd_mach_arm_XScale, "xscale", false, NULL ) 14260484Sobrien}; 14360484Sobrien 14460484Sobrienconst bfd_arch_info_type bfd_arm_arch = 14560484Sobrien N( 0, "arm", true, & arch_info_struct[0] ); 146