1/* BFD library support routines for the Renesas H8/300 architecture. 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 2000, 2001, 2002, 3 2003, 2004 Free Software Foundation, Inc. 4 Hacked by Steve Chamberlain of Cygnus Support. 5 6 This file is part of BFD, the Binary File Descriptor library. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 21 22#include "bfd.h" 23#include "sysdep.h" 24#include "libbfd.h" 25 26static bfd_boolean 27h8300_scan (const struct bfd_arch_info *info, const char *string) 28{ 29 if (*string != 'h' && *string != 'H') 30 return FALSE; 31 32 string++; 33 if (*string != '8') 34 return FALSE; 35 36 string++; 37 if (*string == '/') 38 string++; 39 40 if (*string != '3') 41 return FALSE; 42 string++; 43 if (*string != '0') 44 return FALSE; 45 string++; 46 if (*string != '0') 47 return FALSE; 48 string++; 49 if (*string == '-') 50 string++; 51 52 /* In ELF linker scripts, we typically express the architecture/machine 53 as architecture:machine. 54 55 So if we've matched so far and encounter a colon, try to match the 56 string following the colon. */ 57 if (*string == ':') 58 { 59 string++; 60 return h8300_scan (info, string); 61 } 62 63 if (*string == 'h' || *string == 'H') 64 { 65 string++; 66 if (*string == 'n' || *string == 'N') 67 return (info->mach == bfd_mach_h8300hn); 68 69 return (info->mach == bfd_mach_h8300h); 70 } 71 else if (*string == 's' || *string == 'S') 72 { 73 string++; 74 if (*string == 'n' || *string == 'N') 75 return (info->mach == bfd_mach_h8300sn); 76 77 if (*string == 'x' || *string == 'X') 78 { 79 string++; 80 if (*string == 'n' || *string == 'N') 81 return (info->mach == bfd_mach_h8300sxn); 82 83 return (info->mach == bfd_mach_h8300sx); 84 } 85 86 return (info->mach == bfd_mach_h8300s); 87 } 88 else 89 return info->mach == bfd_mach_h8300; 90} 91 92/* This routine is provided two arch_infos and works out the machine 93 which would be compatible with both and returns a pointer to its 94 info structure. */ 95 96static const bfd_arch_info_type * 97compatible (const bfd_arch_info_type *in, const bfd_arch_info_type *out) 98{ 99 if (in->arch != out->arch) 100 return 0; 101 if (in->mach == bfd_mach_h8300sx && out->mach == bfd_mach_h8300s) 102 return in; 103 if (in->mach == bfd_mach_h8300s && out->mach == bfd_mach_h8300sx) 104 return out; 105 if (in->mach == bfd_mach_h8300sxn && out->mach == bfd_mach_h8300sn) 106 return in; 107 if (in->mach == bfd_mach_h8300sn && out->mach == bfd_mach_h8300sxn) 108 return out; 109 /* It's really not a good idea to mix and match modes. */ 110 if (in->mach != out->mach) 111 return 0; 112 else 113 return in; 114} 115 116static const bfd_arch_info_type h8300sxn_info_struct = 117{ 118 32, /* 32 bits in a word */ 119 16, /* 16 bits in an address */ 120 8, /* 8 bits in a byte */ 121 bfd_arch_h8300, 122 bfd_mach_h8300sxn, 123 "h8300sxn", /* arch_name */ 124 "h8300sxn", /* printable name */ 125 1, 126 FALSE, /* the default machine */ 127 compatible, 128 h8300_scan, 129 0 130}; 131 132static const bfd_arch_info_type h8300sx_info_struct = 133{ 134 32, /* 32 bits in a word */ 135 32, /* 32 bits in an address */ 136 8, /* 8 bits in a byte */ 137 bfd_arch_h8300, 138 bfd_mach_h8300sx, 139 "h8300sx", /* arch_name */ 140 "h8300sx", /* printable name */ 141 1, 142 FALSE, /* the default machine */ 143 compatible, 144 h8300_scan, 145 &h8300sxn_info_struct 146}; 147 148static const bfd_arch_info_type h8300sn_info_struct = 149{ 150 32, /* 32 bits in a word. */ 151 16, /* 16 bits in an address. */ 152 8, /* 8 bits in a byte. */ 153 bfd_arch_h8300, 154 bfd_mach_h8300sn, 155 "h8300sn", /* Architecture name. */ 156 "h8300sn", /* Printable name. */ 157 1, 158 FALSE, /* The default machine. */ 159 compatible, 160 h8300_scan, 161 &h8300sx_info_struct 162}; 163 164static const bfd_arch_info_type h8300hn_info_struct = 165{ 166 32, /* 32 bits in a word. */ 167 16, /* 16 bits in an address. */ 168 8, /* 8 bits in a byte. */ 169 bfd_arch_h8300, 170 bfd_mach_h8300hn, 171 "h8300hn", /* Architecture name. */ 172 "h8300hn", /* Printable name. */ 173 1, 174 FALSE, /* The default machine. */ 175 compatible, 176 h8300_scan, 177 &h8300sn_info_struct 178}; 179 180static const bfd_arch_info_type h8300s_info_struct = 181{ 182 32, /* 32 bits in a word. */ 183 32, /* 32 bits in an address. */ 184 8, /* 8 bits in a byte. */ 185 bfd_arch_h8300, 186 bfd_mach_h8300s, 187 "h8300s", /* Architecture name. */ 188 "h8300s", /* Printable name. */ 189 1, 190 FALSE, /* The default machine. */ 191 compatible, 192 h8300_scan, 193 & h8300hn_info_struct 194}; 195 196static const bfd_arch_info_type h8300h_info_struct = 197{ 198 32, /* 32 bits in a word. */ 199 32, /* 32 bits in an address. */ 200 8, /* 8 bits in a byte. */ 201 bfd_arch_h8300, 202 bfd_mach_h8300h, 203 "h8300h", /* Architecture name. */ 204 "h8300h", /* Printable name. */ 205 1, 206 FALSE, /* The default machine. */ 207 compatible, 208 h8300_scan, 209 &h8300s_info_struct 210}; 211 212const bfd_arch_info_type bfd_h8300_arch = 213{ 214 16, /* 16 bits in a word. */ 215 16, /* 16 bits in an address. */ 216 8, /* 8 bits in a byte. */ 217 bfd_arch_h8300, 218 bfd_mach_h8300, 219 "h8300", /* Architecture name. */ 220 "h8300", /* Printable name. */ 221 1, 222 TRUE, /* The default machine. */ 223 compatible, 224 h8300_scan, 225 &h8300h_info_struct 226}; 227 228/* Pad the given address to 32 bits, converting 16-bit and 24-bit 229 addresses into the values they would have had on a h8s target. */ 230 231bfd_vma 232bfd_h8300_pad_address (bfd *abfd, bfd_vma address) 233{ 234 /* Cope with bfd_vma's larger than 32 bits. */ 235 address &= 0xffffffffu; 236 237 switch (bfd_get_mach (abfd)) 238 { 239 case bfd_mach_h8300: 240 case bfd_mach_h8300hn: 241 case bfd_mach_h8300sn: 242 case bfd_mach_h8300sxn: 243 /* Sign extend a 16-bit address. */ 244 if (address >= 0x8000) 245 return address | 0xffff0000u; 246 return address; 247 248 case bfd_mach_h8300h: 249 /* Sign extend a 24-bit address. */ 250 if (address >= 0x800000) 251 return address | 0xff000000u; 252 return address; 253 254 case bfd_mach_h8300s: 255 case bfd_mach_h8300sx: 256 return address; 257 258 default: 259 abort (); 260 } 261} 262