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, 2005, 2007 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 3 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, 21 MA 02110-1301, USA. */ 22 23 #include "sysdep.h" 24 #include "bfd.h" 25 #include "libbfd.h" 26 27 static bfd_boolean 28 h8300_scan (const struct bfd_arch_info *info, const char *string) 29 { 30 if (*string != 'h' && *string != 'H') 31 return FALSE; 32 33 string++; 34 if (*string != '8') 35 return FALSE; 36 37 string++; 38 if (*string == '/') 39 string++; 40 41 if (*string != '3') 42 return FALSE; 43 string++; 44 if (*string != '0') 45 return FALSE; 46 string++; 47 if (*string != '0') 48 return FALSE; 49 string++; 50 if (*string == '-') 51 string++; 52 53 /* In ELF linker scripts, we typically express the architecture/machine 54 as architecture:machine. 55 56 So if we've matched so far and encounter a colon, try to match the 57 string following the colon. */ 58 if (*string == ':') 59 { 60 string++; 61 return h8300_scan (info, string); 62 } 63 64 if (*string == 'h' || *string == 'H') 65 { 66 string++; 67 if (*string == 'n' || *string == 'N') 68 return (info->mach == bfd_mach_h8300hn); 69 70 return (info->mach == bfd_mach_h8300h); 71 } 72 else if (*string == 's' || *string == 'S') 73 { 74 string++; 75 if (*string == 'n' || *string == 'N') 76 return (info->mach == bfd_mach_h8300sn); 77 78 if (*string == 'x' || *string == 'X') 79 { 80 string++; 81 if (*string == 'n' || *string == 'N') 82 return (info->mach == bfd_mach_h8300sxn); 83 84 return (info->mach == bfd_mach_h8300sx); 85 } 86 87 return (info->mach == bfd_mach_h8300s); 88 } 89 else 90 return info->mach == bfd_mach_h8300; 91 } 92 93 /* This routine is provided two arch_infos and works out the machine 94 which would be compatible with both and returns a pointer to its 95 info structure. */ 96 97 static const bfd_arch_info_type * 98 compatible (const bfd_arch_info_type *in, const bfd_arch_info_type *out) 99 { 100 if (in->arch != out->arch) 101 return 0; 102 if (in->mach == bfd_mach_h8300sx && out->mach == bfd_mach_h8300s) 103 return in; 104 if (in->mach == bfd_mach_h8300s && out->mach == bfd_mach_h8300sx) 105 return out; 106 if (in->mach == bfd_mach_h8300sxn && out->mach == bfd_mach_h8300sn) 107 return in; 108 if (in->mach == bfd_mach_h8300sn && out->mach == bfd_mach_h8300sxn) 109 return out; 110 /* It's really not a good idea to mix and match modes. */ 111 if (in->mach != out->mach) 112 return 0; 113 else 114 return in; 115 } 116 117 static const bfd_arch_info_type h8300sxn_info_struct = 118 { 119 32, /* 32 bits in a word */ 120 16, /* 16 bits in an address */ 121 8, /* 8 bits in a byte */ 122 bfd_arch_h8300, 123 bfd_mach_h8300sxn, 124 "h8300sxn", /* arch_name */ 125 "h8300sxn", /* printable name */ 126 1, 127 FALSE, /* the default machine */ 128 compatible, 129 h8300_scan, 130 bfd_arch_default_fill, 131 0 132 }; 133 134 static const bfd_arch_info_type h8300sx_info_struct = 135 { 136 32, /* 32 bits in a word */ 137 32, /* 32 bits in an address */ 138 8, /* 8 bits in a byte */ 139 bfd_arch_h8300, 140 bfd_mach_h8300sx, 141 "h8300sx", /* arch_name */ 142 "h8300sx", /* printable name */ 143 1, 144 FALSE, /* the default machine */ 145 compatible, 146 h8300_scan, 147 bfd_arch_default_fill, 148 &h8300sxn_info_struct 149 }; 150 151 static const bfd_arch_info_type h8300sn_info_struct = 152 { 153 32, /* 32 bits in a word. */ 154 16, /* 16 bits in an address. */ 155 8, /* 8 bits in a byte. */ 156 bfd_arch_h8300, 157 bfd_mach_h8300sn, 158 "h8300sn", /* Architecture name. */ 159 "h8300sn", /* Printable name. */ 160 1, 161 FALSE, /* The default machine. */ 162 compatible, 163 h8300_scan, 164 bfd_arch_default_fill, 165 &h8300sx_info_struct 166 }; 167 168 static const bfd_arch_info_type h8300hn_info_struct = 169 { 170 32, /* 32 bits in a word. */ 171 16, /* 16 bits in an address. */ 172 8, /* 8 bits in a byte. */ 173 bfd_arch_h8300, 174 bfd_mach_h8300hn, 175 "h8300hn", /* Architecture name. */ 176 "h8300hn", /* Printable name. */ 177 1, 178 FALSE, /* The default machine. */ 179 compatible, 180 h8300_scan, 181 bfd_arch_default_fill, 182 &h8300sn_info_struct 183 }; 184 185 static const bfd_arch_info_type h8300s_info_struct = 186 { 187 32, /* 32 bits in a word. */ 188 32, /* 32 bits in an address. */ 189 8, /* 8 bits in a byte. */ 190 bfd_arch_h8300, 191 bfd_mach_h8300s, 192 "h8300s", /* Architecture name. */ 193 "h8300s", /* Printable name. */ 194 1, 195 FALSE, /* The default machine. */ 196 compatible, 197 h8300_scan, 198 bfd_arch_default_fill, 199 & h8300hn_info_struct 200 }; 201 202 static const bfd_arch_info_type h8300h_info_struct = 203 { 204 32, /* 32 bits in a word. */ 205 32, /* 32 bits in an address. */ 206 8, /* 8 bits in a byte. */ 207 bfd_arch_h8300, 208 bfd_mach_h8300h, 209 "h8300h", /* Architecture name. */ 210 "h8300h", /* Printable name. */ 211 1, 212 FALSE, /* The default machine. */ 213 compatible, 214 h8300_scan, 215 bfd_arch_default_fill, 216 &h8300s_info_struct 217 }; 218 219 const bfd_arch_info_type bfd_h8300_arch = 220 { 221 16, /* 16 bits in a word. */ 222 16, /* 16 bits in an address. */ 223 8, /* 8 bits in a byte. */ 224 bfd_arch_h8300, 225 bfd_mach_h8300, 226 "h8300", /* Architecture name. */ 227 "h8300", /* Printable name. */ 228 1, 229 TRUE, /* The default machine. */ 230 compatible, 231 h8300_scan, 232 bfd_arch_default_fill, 233 &h8300h_info_struct 234 }; 235 236 /* Pad the given address to 32 bits, converting 16-bit and 24-bit 237 addresses into the values they would have had on a h8s target. */ 238 239 bfd_vma 240 bfd_h8300_pad_address (bfd *abfd, bfd_vma address) 241 { 242 /* Cope with bfd_vma's larger than 32 bits. */ 243 address &= 0xffffffffu; 244 245 switch (bfd_get_mach (abfd)) 246 { 247 case bfd_mach_h8300: 248 case bfd_mach_h8300hn: 249 case bfd_mach_h8300sn: 250 case bfd_mach_h8300sxn: 251 /* Sign extend a 16-bit address. */ 252 if (address >= 0x8000) 253 return address | 0xffff0000u; 254 return address; 255 256 case bfd_mach_h8300h: 257 /* Sign extend a 24-bit address. */ 258 if (address >= 0x800000) 259 return address | 0xff000000u; 260 return address; 261 262 case bfd_mach_h8300s: 263 case bfd_mach_h8300sx: 264 return address; 265 266 default: 267 abort (); 268 } 269 } 270