Back to index

cell-binutils  2.17cvs20070401
cpu-h8300.c
Go to the documentation of this file.
00001 /* BFD library support routines for the Renesas H8/300 architecture.
00002    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 2000, 2001, 2002,
00003    2003, 2004 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
00027 h8300_scan (const struct bfd_arch_info *info, const char *string)
00028 {
00029   if (*string != 'h' && *string != 'H')
00030     return FALSE;
00031 
00032   string++;
00033   if (*string != '8')
00034     return FALSE;
00035 
00036   string++;
00037   if (*string == '/')
00038     string++;
00039 
00040   if (*string != '3')
00041     return FALSE;
00042   string++;
00043   if (*string != '0')
00044     return FALSE;
00045   string++;
00046   if (*string != '0')
00047     return FALSE;
00048   string++;
00049   if (*string == '-')
00050     string++;
00051 
00052   /* In ELF linker scripts, we typically express the architecture/machine
00053      as architecture:machine.
00054 
00055      So if we've matched so far and encounter a colon, try to match the
00056      string following the colon.  */
00057   if (*string == ':')
00058     {
00059       string++;
00060       return h8300_scan (info, string);
00061     }
00062 
00063   if (*string == 'h' || *string == 'H')
00064     {
00065       string++;
00066       if (*string == 'n' || *string == 'N')
00067        return (info->mach == bfd_mach_h8300hn);
00068 
00069       return (info->mach == bfd_mach_h8300h);
00070     }
00071   else if (*string == 's' || *string == 'S')
00072     {
00073       string++;
00074       if (*string == 'n' || *string == 'N')
00075        return (info->mach == bfd_mach_h8300sn);
00076 
00077       if (*string == 'x' || *string == 'X')
00078        {
00079          string++;
00080          if (*string == 'n' || *string == 'N')
00081            return (info->mach == bfd_mach_h8300sxn);
00082 
00083          return (info->mach == bfd_mach_h8300sx);
00084        }
00085       
00086       return (info->mach == bfd_mach_h8300s);
00087     }
00088   else
00089     return info->mach == bfd_mach_h8300;
00090 }
00091 
00092 /* This routine is provided two arch_infos and works out the machine
00093    which would be compatible with both and returns a pointer to its
00094    info structure.  */
00095 
00096 static const bfd_arch_info_type *
00097 compatible (const bfd_arch_info_type *in, const bfd_arch_info_type *out)
00098 {
00099   if (in->arch != out->arch)
00100     return 0;
00101   if (in->mach == bfd_mach_h8300sx && out->mach == bfd_mach_h8300s)
00102     return in;
00103   if (in->mach == bfd_mach_h8300s && out->mach == bfd_mach_h8300sx)
00104     return out;
00105   if (in->mach == bfd_mach_h8300sxn && out->mach == bfd_mach_h8300sn)
00106     return in;
00107   if (in->mach == bfd_mach_h8300sn && out->mach == bfd_mach_h8300sxn)
00108     return out;
00109   /* It's really not a good idea to mix and match modes.  */
00110   if (in->mach != out->mach)
00111     return 0;
00112   else
00113     return in;
00114 }
00115 
00116 static const bfd_arch_info_type h8300sxn_info_struct =
00117 {
00118   32,                       /* 32 bits in a word */
00119   16,                       /* 16 bits in an address */
00120   8,                        /* 8 bits in a byte */
00121   bfd_arch_h8300,
00122   bfd_mach_h8300sxn,
00123   "h8300sxn",               /* arch_name  */
00124   "h8300sxn",               /* printable name */
00125   1,
00126   FALSE,                    /* the default machine */
00127   compatible,
00128   h8300_scan,
00129   0
00130 };
00131 
00132 static const bfd_arch_info_type h8300sx_info_struct =
00133 {
00134   32,                       /* 32 bits in a word */
00135   32,                       /* 32 bits in an address */
00136   8,                        /* 8 bits in a byte */
00137   bfd_arch_h8300,
00138   bfd_mach_h8300sx,
00139   "h8300sx",                /* arch_name  */
00140   "h8300sx",                /* printable name */
00141   1,
00142   FALSE,                    /* the default machine */
00143   compatible,
00144   h8300_scan,
00145   &h8300sxn_info_struct
00146 };
00147 
00148 static const bfd_arch_info_type h8300sn_info_struct =
00149 {
00150   32,                       /* 32 bits in a word.  */
00151   16,                       /* 16 bits in an address.  */
00152   8,                        /* 8 bits in a byte.  */
00153   bfd_arch_h8300,
00154   bfd_mach_h8300sn,
00155   "h8300sn",                /* Architecture name.  */
00156   "h8300sn",                /* Printable name.  */
00157   1,
00158   FALSE,                    /* The default machine.  */
00159   compatible,
00160   h8300_scan,
00161   &h8300sx_info_struct
00162 };
00163 
00164 static const bfd_arch_info_type h8300hn_info_struct =
00165 {
00166   32,                       /* 32 bits in a word.  */
00167   16,                       /* 16 bits in an address.  */
00168   8,                        /* 8 bits in a byte.  */
00169   bfd_arch_h8300,
00170   bfd_mach_h8300hn,
00171   "h8300hn",                /* Architecture name.  */
00172   "h8300hn",                /* Printable name.  */
00173   1,
00174   FALSE,                    /* The default machine.  */
00175   compatible,
00176   h8300_scan,
00177   &h8300sn_info_struct
00178 };
00179 
00180 static const bfd_arch_info_type h8300s_info_struct =
00181 {
00182   32,                       /* 32 bits in a word.  */
00183   32,                       /* 32 bits in an address.  */
00184   8,                        /* 8 bits in a byte.  */
00185   bfd_arch_h8300,
00186   bfd_mach_h8300s,
00187   "h8300s",                 /* Architecture name.  */
00188   "h8300s",                 /* Printable name.  */
00189   1,
00190   FALSE,                    /* The default machine.  */
00191   compatible,
00192   h8300_scan,
00193   & h8300hn_info_struct
00194 };
00195 
00196 static const bfd_arch_info_type h8300h_info_struct =
00197 {
00198   32,                       /* 32 bits in a word.  */
00199   32,                       /* 32 bits in an address.  */
00200   8,                        /* 8 bits in a byte.  */
00201   bfd_arch_h8300,
00202   bfd_mach_h8300h,
00203   "h8300h",                 /* Architecture name.  */
00204   "h8300h",                 /* Printable name.  */
00205   1,
00206   FALSE,                    /* The default machine.  */
00207   compatible,
00208   h8300_scan,
00209   &h8300s_info_struct
00210 };
00211 
00212 const bfd_arch_info_type bfd_h8300_arch =
00213 {
00214   16,                       /* 16 bits in a word.  */
00215   16,                       /* 16 bits in an address.  */
00216   8,                        /* 8 bits in a byte.  */
00217   bfd_arch_h8300,
00218   bfd_mach_h8300,
00219   "h8300",                  /* Architecture name.  */
00220   "h8300",                  /* Printable name.  */
00221   1,
00222   TRUE,                            /* The default machine.  */
00223   compatible,
00224   h8300_scan,
00225   &h8300h_info_struct
00226 };
00227 
00228 /* Pad the given address to 32 bits, converting 16-bit and 24-bit
00229    addresses into the values they would have had on a h8s target.  */
00230 
00231 bfd_vma
00232 bfd_h8300_pad_address (bfd *abfd, bfd_vma address)
00233 {
00234   /* Cope with bfd_vma's larger than 32 bits.  */
00235   address &= 0xffffffffu;
00236 
00237   switch (bfd_get_mach (abfd))
00238     {
00239     case bfd_mach_h8300:
00240     case bfd_mach_h8300hn:
00241     case bfd_mach_h8300sn:
00242     case bfd_mach_h8300sxn:
00243       /* Sign extend a 16-bit address.  */
00244       if (address >= 0x8000)
00245        return address | 0xffff0000u;
00246       return address;
00247 
00248     case bfd_mach_h8300h:
00249       /* Sign extend a 24-bit address.  */
00250       if (address >= 0x800000)
00251        return address | 0xff000000u;
00252       return address;
00253 
00254     case bfd_mach_h8300s:
00255     case bfd_mach_h8300sx:
00256       return address;
00257 
00258     default:
00259       abort ();
00260     }
00261 }