Back to index

cell-binutils  2.17cvs20070401
cpu-i960.c
Go to the documentation of this file.
00001 /* BFD library support routines for the i960 architecture.
00002    Copyright 1990, 1991, 1993, 1994, 1996, 1999, 2000, 2001, 2002, 2006
00003    Free Software Foundation, Inc.
00004    Hacked by Steve Chamberlain of Cygnus Support.
00005 
00006    This file is part of BFD, the Binary File Descriptor library.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00021 
00022 #include "bfd.h"
00023 #include "sysdep.h"
00024 #include "libbfd.h"
00025 
00026 static bfd_boolean scan_960_mach
00027   PARAMS ((const bfd_arch_info_type *, const char *));
00028 static const bfd_arch_info_type *compatible
00029   PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *));
00030 
00031 /* This routine is provided a string, and tries to work out if it
00032    could possibly refer to the i960 machine pointed at in the
00033    info_struct pointer */
00034 
00035 static bfd_boolean
00036 scan_960_mach (ap, string)
00037      const bfd_arch_info_type *ap;
00038      const char *string;
00039 {
00040   unsigned long machine;
00041   int fail_because_not_80960 = FALSE;
00042 
00043   /* Look for the string i960 at the front of the string.  */
00044   if (strncasecmp ("i960", string, 4) == 0)
00045     {
00046       string += 4;
00047 
00048       /* i960 on it's own means core to us.  */
00049       if (* string == 0)
00050        return ap->mach == bfd_mach_i960_core;
00051 
00052       /* "i960:*" is valid, anything else is not.  */
00053       if (* string != ':')
00054        return FALSE;
00055 
00056       string ++;
00057     }
00058   /* In some bfds the cpu-id is written as "80960KA", "80960KB",
00059      "80960CA" or "80960MC".  */
00060   else if (CONST_STRNEQ (string, "80960"))
00061     {
00062       string += 5;
00063 
00064       /* Set this to TRUE here.  If a correct matching postfix
00065         is detected below it will be reset to FALSE.  */
00066       fail_because_not_80960 = TRUE;
00067     }
00068   /* No match, can't be us.  */
00069   else
00070     return FALSE;
00071 
00072   if (* string == '\0')
00073     return FALSE;
00074 
00075   if (string[0] == 'c' && string[1] == 'o' && string[2] == 'r' &&
00076       string[3] == 'e' && string[4] == '\0')
00077     machine = bfd_mach_i960_core;
00078   else if (strcasecmp (string, "ka_sa") == 0)
00079     machine = bfd_mach_i960_ka_sa;
00080   else if (strcasecmp (string, "kb_sb") == 0)
00081     machine = bfd_mach_i960_kb_sb;
00082   else if (string[1] == '\0' || string[2] != '\0') /* rest are 2-char.  */
00083     return FALSE;
00084   else if (string[0] == 'k' && string[1] == 'b')
00085     { machine = bfd_mach_i960_kb_sb; fail_because_not_80960 = FALSE; }
00086   else if (string[0] == 's' && string[1] == 'b')
00087     machine = bfd_mach_i960_kb_sb;
00088   else if (string[0] == 'm' && string[1] == 'c')
00089     { machine = bfd_mach_i960_mc; fail_because_not_80960 = FALSE; }
00090   else if (string[0] == 'x' && string[1] == 'a')
00091     machine = bfd_mach_i960_xa;
00092   else if (string[0] == 'c' && string[1] == 'a')
00093     { machine = bfd_mach_i960_ca; fail_because_not_80960 = FALSE; }
00094   else if (string[0] == 'k' && string[1] == 'a')
00095     { machine = bfd_mach_i960_ka_sa; fail_because_not_80960 = FALSE; }
00096   else if (string[0] == 's' && string[1] == 'a')
00097     machine = bfd_mach_i960_ka_sa;
00098   else if (string[0] == 'j' && string[1] == 'x')
00099     machine = bfd_mach_i960_jx;
00100   else if (string[0] == 'h' && string[1] == 'x')
00101     machine = bfd_mach_i960_hx;
00102   else
00103     return FALSE;
00104 
00105   if (fail_because_not_80960)
00106     return FALSE;
00107 
00108   if (machine == ap->mach)
00109     return TRUE;
00110 
00111   return FALSE;
00112 }
00113 
00114 /* This routine is provided two arch_infos and works out the i960
00115    machine which would be compatible with both and returns a pointer
00116    to its info structure */
00117 
00118 static const bfd_arch_info_type *
00119 compatible (a,b)
00120      const bfd_arch_info_type *a;
00121      const bfd_arch_info_type *b;
00122 {
00123 
00124   /* The i960 has distinct subspecies which may not interbreed:
00125        CORE CA
00126        CORE KA KB MC XA
00127        CORE HX JX
00128      Any architecture on the same line is compatible, the one on
00129      the right is the least restrictive.
00130 
00131      We represent this information in an array, each machine to a side */
00132 
00133 #define ERROR 0
00134 #define CORE  bfd_mach_i960_core  /*1*/
00135 #define KA    bfd_mach_i960_ka_sa /*2*/
00136 #define KB    bfd_mach_i960_kb_sb /*3*/
00137 #define MC    bfd_mach_i960_mc    /*4*/
00138 #define XA    bfd_mach_i960_xa    /*5*/
00139 #define CA    bfd_mach_i960_ca    /*6*/
00140 #define JX    bfd_mach_i960_jx    /*7*/
00141 #define HX    bfd_mach_i960_hx    /*8*/
00142 #define MAX_ARCH ((int)HX)
00143 
00144   static const unsigned long matrix[MAX_ARCH+1][MAX_ARCH+1] =
00145     {
00146       { ERROR,       CORE,  KA,    KB,    MC,    XA,    CA,    JX,    HX },
00147       { CORE, CORE,  KA,    KB,    MC,    XA,    CA,    JX,    HX },
00148       { KA,   KA,    KA,    KB,    MC,    XA,    ERROR, ERROR, ERROR},
00149       { KB,   KB,    KB,    KB,    MC,    XA,    ERROR,        ERROR, ERROR},
00150       { MC,   MC,    MC,    MC,    MC,    XA,    ERROR, ERROR, ERROR},
00151       { XA,   XA,    XA,    XA,    XA,    XA,    ERROR, ERROR, ERROR},
00152       { CA,   CA,    ERROR, ERROR, ERROR, ERROR, CA,    ERROR, ERROR},
00153       { JX,   JX,    ERROR, ERROR, ERROR, ERROR, ERROR,  JX,   HX },
00154       { HX,   HX,    ERROR, ERROR, ERROR, ERROR, ERROR, HX,    HX },
00155     };
00156 
00157   if (a->arch != b->arch || matrix[a->mach][b->mach] == ERROR)
00158     {
00159     return NULL;
00160     }
00161   else
00162     {
00163     return (a->mach  ==  matrix[a->mach][b->mach]) ?  a : b;
00164     }
00165 }
00166 
00167 #define N(a,b,d,n) \
00168 { 32, 32, 8,bfd_arch_i960,a,"i960",b,3,d,compatible,scan_960_mach,n,}
00169 
00170 static const bfd_arch_info_type arch_info_struct[] =
00171 {
00172   N(bfd_mach_i960_ka_sa,"i960:ka_sa",FALSE, &arch_info_struct[1]),
00173   N(bfd_mach_i960_kb_sb,"i960:kb_sb",FALSE, &arch_info_struct[2]),
00174   N(bfd_mach_i960_mc,   "i960:mc",   FALSE, &arch_info_struct[3]),
00175   N(bfd_mach_i960_xa,   "i960:xa",   FALSE, &arch_info_struct[4]),
00176   N(bfd_mach_i960_ca,   "i960:ca",   FALSE, &arch_info_struct[5]),
00177   N(bfd_mach_i960_jx,   "i960:jx",   FALSE, &arch_info_struct[6]),
00178   N(bfd_mach_i960_hx,       "i960:hx",   FALSE, 0),
00179 };
00180 
00181 const bfd_arch_info_type bfd_i960_arch =
00182   N(bfd_mach_i960_core, "i960:core", TRUE, &arch_info_struct[0]);